関数レベルでのインポートがよりモジュール化されているとは確信していません。Python 内のモジュールから関数 (またはクラス) をインポートすると、ライブラリの依存関係が解決され、それらのインポートされた関数は同じライブラリをインポートしなくても機能します。
(注:モジュールを1語おきに言うのを避けるためにライブラリを使用しています)
例:
my_module.py
import sys
def printerr(message):
"""Use stderr for error messages"""
sys.stderr.write('{0}\n'.format(message))
sys.stderr.flush()
my_script.py
import os
from my_module import printerr
def main():
"""Derpy script"""
if 'my_important_file.txt' in os.listdir():
print("it's there")
else:
printerr("ERROR: Unable to find important file")
これは非常に単純化された例ですが、printerr 内に sys をインポートしてもモジュール化されません。どちらの方法でも同様にモジュール化されます。
私の経験では、発生する可能性があり実際に発生する問題は、モジュール化に関しては技術的負債の蓄積に関連しています。
最初は、何をするのか明確に定義された単純なモジュールがあります。そのモジュール内にインポートされたライブラリは理にかなっていて、その中の関数/クラス全体でよく使用されています。
時間が経ち、機能が追加されると、新しい関数/クラスを「最適な」モジュールに追加することがよくあります (つまり、「それをここに置くのは理にかなっていると思いますか?」)。
時間が経つにつれ、より優れたライブラリが人気が出てきたので、それを使用しますが、古いコードをすべて置き換えるのに数週間を費やしたくありません (そのような時間があるので、作る!)。
やがて、20 ものものをインポートし、多くのことを行う危険なコードができあがります。そしてもちろん単体テストもないので、触るたびに何かが壊れてしまうのですが、それがわかるまでに1週間はかかります…
あなたはこれにうんざりしているので、それを台無しにしてください。それを使用する関数内で必要なものをインポートするだけです。これは、約 20 のインポートを処理するよりも簡単です。
関数内でインポートしない非常に説得力のある理由は、次のようによく示されています。
def doh():
import nothing
print "Homer says..."
doh が単体テストで呼び出されなかったため、これは出荷したばかりのバグですが、考えもしなかった奇妙な方法で呼び出されます。「PEP8が言ったようにインポートさえすれば、この問題は発生しませんでした。」