2011-07-27 247 views
15

我目前正在學習Python,而且我必須在Python 2.7項目上工作。訪問「模塊範圍」vars

訪問「模塊範圍」變量模塊本身的功能是一個有點混亂,對我來說,我沒有找到一個令人滿意的方式成功。

我嘗試至今:

方法1:

my_module.py

my_global_var = None 

def my_func(): 
    global my_global_var 
    my_global_var = 'something_else' 

在這裏,我想混淆局部和 「模塊範圍」 瓦爾可能是相當容易的。

方式2:

my_module.py

import my_module 

my_global_var = None 

def my_func(): 
    my_module.my_global_var = 'something_else' 

這裏, 「my_module」 的名字不能那麼容易改變的 「方式1」 在必要的時候。另外,將模塊導入本身聽起來很奇怪。

你會推薦什麼?或者你會建議別的嗎?謝謝。

+1

不要使用'路2',使用'路1'。 Python範圍和作業很有趣。當從名字中讀取數值時,解釋器將始終從最內側的範圍向外搜索名稱。當你爲當前範圍內的名稱賦值時,這意味着,如果您將'my_global_var'分配給不帶'global'關鍵字的模塊,則從嵌套範圍分配的角度來看,模塊將具有兩個不同的'my_global_var',並超出嵌套範圍。全局聲明只是告訴解釋器爲'my_global_var'這個名字賦值'global'作用域。 – Matt

回答

19

你可能想在Python's namespaces閱讀起來。方法1是正確的,但一般是不必要的,從來沒有使用2.更容易的方法是隻使用一個字典(或類或其他物體):

my_globals = {'var': None} 

def my_func(): 
    my_globals['var'] = 'something else' 

分配總是進入最裏面的範圍,最裏面的範圍始終首先搜索,因此需要全局關鍵字。在這種情況下,你不是指定一個名字,所以它是不必要的。

+3

啊。因此可以在函數作用域中修改字典值,但不能修改原始字符串值。 Python在這裏似乎非常直觀。無論如何,這工作,並適合我的需要。謝謝 –

+0

賦值總是進入最內層的範圍,並且總是先搜索,因此需要'global'關鍵字。在這種情況下,你沒有分配一個名字,所以它是不必要的(Python會搜索最內層的範圍,並且不會找到my_globals最終到達模塊級範圍 – zeekay

+0

感謝這個行爲的詳細解釋。 –

3

路1是正確的方式,當你絕對必須重新綁定一個全局變量。然而,你應該問自己,爲什麼你要修改一個全局的東西,以及是否有更好的東西可以做(比如封裝類中的行爲)。

應該避免將模塊導入自身,因爲它容易出錯。如果模塊也是腳本,則有時需要導入__main__,或者如果該模塊是包的一部分,則可能應該導入foo.my_module。總之,不要那樣做。

1

避免設置全局變量。你可以很容易地用類創建新的名字空間,所以如果你必須使用類變量。

對於任何嚴肅的事情,您需要一個適當的設計與類反正。

+1

感謝您的回答。我想創建一個單例,推薦的方法似乎只是創建一個模塊(請參閱http://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons- in-python),所以我寧願避免在這個特定情況下的類。 –

+0

@FrostyZ - 我建議不要使用模塊作爲單例,如果沒有其他原因,那麼會導致單元測試非常困難。請參閱

+0

即使對於測試,某些單身人士似乎也可以接受(例如記錄器)。請參閱http://googletesting.blogspot.com/2008/08/root-cause-of-singletons.html –

3

導入內本身就是一個模塊可以產生有害的副作用(如評估報告不止一次。)我會建議使用「方法1」等pylint的一種工具來幫助驗證您的代碼並執行共同的做法。

pylint的可以在這裏找到:http://www.logilab.org/project/pylint