13

一部の 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

どちらも意図したとおりに機能しますが、落とし穴がないかどうか、一般的にどちらのアプローチがより推奨されているか、またその理由が知りたいです。

4

3 に答える 3

14

関数を使用execfileすると、設定ファイルが評価されるたびに Python ソース ファイル (.py) が評価されます。毎回 Python パーサーを実行しています。を使用してimportも、必ずしもこれが行われるとは限りません (.pyc ファイルを使用する場合があります)。通常、Python (少なくとも cPython) でプロジェクトを初めて実行すると、バイトコードにコンパイルされ、再度コンパイルされることはありません。あなたはそれを壊しています。これは必ずしも問題ではありませんが、注意する必要があります。

を使用execfileすると、ファイル内にある可能性のあるすべてのインポートが、settings_local.pyファイルのモジュール スコープで再評価されsettings.pyます。を使用すると、モジュール スコープ内import *のすべての項目が含まれます。settings_local.py最終的な効果は同じです (settings_local.pyモジュール スコープに含まれるすべての項目が に含まれますsettings.py) が、方法は異なります。

最後に、モジュールをインクルードするのではなく、モジュールとして実行するのが普通です。コードに などを含めることは合理的ですos.path.dirname(__file__)。コードがこれを使用した場合、作成者が合理的に期待していたモジュールでコードが実行されなくなるため、混乱する可能性があります。

私の経験では、人々はimportnotを使用しますexecfile。Django はまさに「設定より規約」です。規則に従ってください。

于 2012-07-28T19:12:09.843 に答える
8

もう 1 つの違い: 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がグローバルに追加されます。

于 2012-11-02T17:57:32.937 に答える
2

最初のバージョン ( from settings_local import *) は、誰もが期待するものです。また、コード アナライザーがモジュールを見つけられるようになります。

于 2012-07-28T17:52:04.523 に答える