正如你发现全局变量不这样工作 - 他们也不应该。以下是你可以做的一些事情,但不应该。
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