正如你發現全局變量不這樣工作 - 他們也不應該。以下是你可以做的一些事情,但不應該。
myfunctions.py
ref = 30
def f(x):
print x + ref
our_caller.py
import myfunctions
myfunctions.f(10) # prints 40
myfunctions.ref = 50
myfunctions.f(10) # prints 60
但是後來怎麼樣some_other_caller.py?
import myfunctions
myfunctions.f(20) # prints 50? prints 70?
這取決於當你與myfunctions模塊中的全局變量混亂周圍。
另外,作爲一個思想實驗,想象你上面發佈的代碼的確如你所期望的那樣工作(它會在某些語言中)。在some_other_caller導入導入myfunctions的our_caller的情況下會發生什麼情況。那麼使用哪個ref?它可能更復雜一些,some_other_caller可以在our_caller中調用函數,然後調用myfunctions.f - 所以我們使用our_caller中的ref?那麼,如果some_other_caller直接調用myfunctions,行爲可能會有所不同?
這不是世界上任何人想住在
做的是更好的方式更像是:
myfunctions.py
def f(x, ref=30):
print x + ref
our_caller.py
import myfunctions
myfunctions.f(10) # prints 40
myfunctions.f(10, ref=50) # prints 60
然後人們可以看到發生了什麼 - 沒有奇怪的狀態改變。全球狀態真的是最好的避免。你會一次又一次地聽到。在你自己的危險(以及後來必須支持你的代碼的任何可憐的靈魂)中忽略這個建議。
編輯:除上述有關您的用例的註釋之外,看到類似以下的模式並不罕見。
REF = 30
ref_count = 0
def f(x, ref=REF, other_thing=None):
if not other_thing:
other_thing = ref_count
print x + ref + other_thing
def add_ref(current_count=None):
global ref_count
if current_count is not None:
ref_count = current_count
ref_count += 1
您可以保留全局變量(REF更像是一個全局常量)。當你從外部調用f時,你可以選擇爲它們提供值或允許它們成爲默認值。此外,您可以調用add_ref,爲其提供一個新值以用於模塊中的全局副本。
同樣,同樣的規則適用 - 您已將全局狀態添加到您的模塊,這可能受外部模塊影響。你需要非常小心誰在改變它,一個更好的架構會首先嚐試避免這種情況。
但是,爲什麼你不顯式傳遞變量作爲函數的參數?顯式通常比隱式更好(並且更清晰)... –
問題不在於'myfunctions' *模塊*具有不同的全局名稱空間。問題是*函數*'f'具有不同的全局名稱空間,它是'myfunctions'模塊的'__dict__'。檢查「f.func_globals」屬性與「myfunctions .__ dict__」相同。這是非常明智的,否則每次使用函數時都必須知道它們所需的所有全局變量。這可能意味着你有*閱讀源代碼,或者所有功能的文檔都會很長。 – Bakuriu
謝謝大家 - 在我的情況下,問題是f實際上是一個相當長的函數,使用大約20個來自主命名空間的變量 - 只要在主模塊中定義了f,我就可以避免(繁瑣的)列表任務所有這些都是論據。這是否意味着如果在單獨的模塊中定義了f,則無法做到這一點? – user2383521