2012-07-28 116 views
11

在我的一些Django應用程序中,我使用settings_local.py文件覆蓋各種環境(例如開發,測試和生產)上不同的設置。我已經最初使用下面的代碼,包括其在settings.py內容:Python:'import *'vs execfile

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 

兩個工作如預期,但我m好奇我是否缺少任何陷阱,一般來說哪種方法更值得推薦,爲什麼。

回答

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__)之類的內容是合理的。如果任何代碼確實使用了這個,你會混淆它,因爲代碼將不再在作者可能合理預期的模塊中執行。

以我的經驗,人們使用import而不是execfile。 Django非常「約定配置」。遵循約定。

+5

'__file__'可以很容易地通過參數提供。主要區別在於,無論執行多少次「import module」,都只導入一次模塊(exec每次調用時執行文件),而「import」不需要顯式路徑指向文件所以它也可以在一個zip檔案裏面工作)。 – jfs 2012-07-28 19:40:19

+0

@ J.F.Sebastian這應該是一個答案。 – Marcin 2012-07-28 21:49:07

+3

我發現有關execfile的一個優點(與導入相反)是我可以動態執行它。具體來說,如果我有一個設置模塊列表,我可以通過列表循環,每個調用execfile。有沒有辦法做到這一點與導入? – 2012-07-29 08:09:43

2

第一個版本(from settings_local import *)是每個人都期望看到的。它也會讓代碼分析器找到模塊。

8

另一個區別: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被加入到全局。

相關問題