Python: 'import *' vs execfile.
-
13-12-2019 - |
質問
私のDjangoアプリの中には、さまざまな環境で異なる設定を上書きするためのsettings_local.py
ファイルを使用しています(例えば開発、テスト、およびプロダクション)。もともと次のコードを使用して、その内容をsettings.py
に含めました:
try:
from settings_local import *
except ImportError:
sys.stderr.write("The settings_local.py file is missing.\n")
DEBUG=False
.
最近execfile
関数を見つけて、次のように切り替えました。
try:
execfile(path.join(PROJECT_ROOT, "settings_local.py"))
except IOError:
sys.stderr.write("The settings_local.py file is missing.\n"
DEBUG=False
.
意図したように機能しますが、私がゴッチャを逃しているかどうか、一般的にどのアプローチがより推奨されているのか、そしてなぜ恐れています。
解決
execfile
関数を使用すると、設定ファイルが評価されるたびにPythonのソースファイル(.py)が評価されます。毎回Pythonパーサーを実行しています。 import
を使用すると、必ずしもこれを行うことはありません(.pycファイルを使用する可能性があります)。一般的に、Python(少なくともCPython)でプロジェクトを初めて実行するときは、バイトコードにコンパイルされ、再度再コンパイルされません。あなたはそれを破っています。これは必ずしも問題ではありませんが、それに注意する必要があります。
execfile
を使用すると、settings_local.py
ファイルのモジュールの範囲では、settings.py
ファイルにあるすべてのインポートが行われている可能性があります。 import *
を使用すると、settings_local.py
モジュールスコープ内のすべての項目が含まれています。ネット効果は同じです(settings_local.py
モジュールの範囲に含まれるすべての項目はsettings.py
に含まれています)が、メソッドは異なります。
最後に、モジュールが含まれるのではなくモジュールとして実行されるのは通常です。 CODEには、os.path.dirname(__file__)
などのものを含めることが合理的です。コードがこれを使用した場合は、著者が合理的に期待されている可能性があるモジュールでコードが実行されなくなったため、コードが混同されなくなります。
私の経験では、人々はimport
を使用していません。 Djangoは「構成上の大会」です。条約に従ってください。
他のヒント
別の違い:execfileコンテキストディクショナリを取得します。デフォルトでは、グローバルコンテキストまたは 指定された辞書。これはいくつかの奇妙なことを可能にする可能性があります
dont_do_this.py
:
# Probably not a good thing to do
z=x+1 # an expression that involves an un-defined field
.
明らかに
from dont_do_this import *
.
失敗します。
しかし
d={'x':1}
execfile( 'dont_do_this.py', d )
.
はOKで、d=={'x':1, 'z':2}
に注意してください
x=1
execfile( 'dont_do_this.py' )
.
はOKで、変数z
がグローバルに追加されます。
最初のバージョン(from settings_local import *
)は、誰もが見えることを期待するものです。また、コードアナライザーにモジュールを見つけることもできます。