我是Python的新手,同时拥有丰富的C和C ++经验。经常让我兴奋的事情之一是希望能够在函数中引用全局变量,如下所示:
# first_time needs to be referenced within foo, but could also
# be modified by a different function, or from the global scope,
# so I try to define it globally
first_time = True
def foo():
if (first_time):
first_time = False
foo()
Python给出了错误,我明白了我是如何违反LGB Rule:
的if (first_time):
UnboundLocalError: local variable 'first_time' referenced before assignment
更新:我找到了部分解决方案,但我不喜欢它:
def foo():
global first_time
if (first_time):
first_time = False
first_time = True
foo()
我不喜欢这个解决方案,我想在声明它的同一行初始化它,但Python似乎不允许我这样做。
此外,它不允许我在另一个函数中执行相同的操作:
def bar():
global first_time
if (first_time):
first_time = False
有没有办法在函数之外声明和初始化它,以便可以通过多个函数检查和更新它?
答案 0 :(得分:3)
你误解了Python global
关键字的作用。
它不声明全局变量。相反,它确保 - 在当前代码块中 - 在全局范围而不是在本地范围内搜索提供的标识符。 (documentation无法解释这种区别)
例如,如果global
实际上在全局范围内声明了变量,则以下代码将起作用:
def bar():
global foo
foo = 1
print(foo)
但它产生了:
Traceback (most recent call last):
File "./test.py", line 5, in <module>
print(foo)
NameError: name 'foo' is not defined
由于global
未声明变量,因此您需要注意两个问题:
global foo
没有根据!如以下代码段所示:
foo = 5
def bar():
global foo
foo += 1
def baz():
global foo
foo += 10
bar()
baz()
bar()
print(foo)
正如预期的那样产生17
。
<强>更新强>
然而,总的来说,全球变量是不受欢迎的。根据具体情况,可能有更好的方法。
Python中一个鲜为人知的技巧是你可以在方法上放置属性(这是方法是对象的结果):
def bar():
bar.foo += 1
bar.foo = 5
print(bar.foo)
bar()
print(bar.foo)
bar.foo = 1
哪个输出5
,6
。
这样,foo
不是全局的,它仅限于bar
的命名空间,但仍可通过bar.foo
全局访问!如果foo
固有属于bar
但需要全局访问,这是一个非常好的解决方案。
一个简单但更具体的例子,说明如何使用它:假设你有一个方法print()
,如下所示:
def print(document, printer=None):
printer = printer or print.printer
printer.send(document)
print.jobcount += 1
print.printer = get_default_printer()
print.jobcount = 0
然后你可以:
print(doc)
print(doc, printer=some_printer)
print.printer = some_printer
print.jobcount
实际上并没有为您的方法print()
命名,因为这已经是一种内置方法; - )
这种方法可能最适合小事。如果它失控了,我更喜欢用类来封装这些东西,即使我只是使用静态方法:
class Print:
printer = get_default_printer()
jobcount = 0
def print(document, printer=None):
printer = printer or Print.printer
printer.send(document)
Print.jobcount += 1
所以你可以做Print.print(doc)
和Print.jobcount
等等......
答案 1 :(得分:1)
可以从本地范围创建一个全局变量,虽然它被认为有点不合理:
def foo():
if not 'first_time' in globals():
globals()['first_time'] = True
else:
global first_time
if (first_time):
first_time = False
globals()
是一个包含所有全局名称的字典(在shell中输入globals()
是有用的)。你可以写信给它。如果是foo
:
>>> first_time
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
first_time
NameError: name 'first_time' is not defined
>>> foo()
>>> first_time
False