我是python的新手,所以可能有一个简单的答案,但我什至不确定要搜索什么。下面是一个简化的代码片段:
testing = 1
print testing
def update():
print "UPDATED"
testing = 2
update()
def test():
new = testing
print new
test()
我的期望是最后的打印是"2",而是"1"。为什么会这样?
我需要这个,以便我可以检查从某个变量的初始化/更新开始的 unix 时间是否与特定函数(包含 while 循环)开始执行的时间相同。让我知道是否有更好的方法来实现这一目标。
如果你打算使用全局变量(这通常是一个坏主意,如果可能的话必须避免),你必须在每个修改testing
的函数中指示变量是全局的,如下所示:
def update():
global testing # mandatory: the variable is being modified
print "UPDATED"
testing = 2
没有必要在test()
中显式使用 global
- 我们只读取值,而我们在 update()
中更改它,但作为全局定义变量的余数很有用
def test():
global testing # not mandatory, but useful as documentation
new = testing
print new
你必须在函数中声明你的变量全局(编写全局测试)。
testing
是update()
函数的局部变量。函数局部变量与模块全局变量完全分开。
如果 Python 在作用域内分配名称,则会将其标记为本地名称。 testing
被分配到 update()
内。 new
在test()
中也被赋值,但在那个函数中testing
不是。这使得testing
,在test
,是一个全球性的。这就是 python 让你找到在你的模块中声明或从另一个模块导入的内置、函数和其他对象的方式。
如果你想赋值到函数中的名字,并且仍然把它当作一个全局的,你需要显式覆盖Python,并告诉它把这个名字当作一个全局的:
def update():
print "UPDATED"
global testing
testing = 2
您可以将 global
语句放置在函数中的任何位置,它将使该特定名称成为整个函数的全局名称。
我会尝试在奥斯卡和马蒂恩已经给出的好答案中添加一些东西。
当你在python中读取一个函数时,任何函数,你都必须读两次。总是。
在第一次传递中,您应该这样做:对于每个global
和nonlocal
声明语句,将它们(概念上)移动到函数的开头。
对于以下形式的每个语句
* x = expr (or "x += expr", "x *= expr", etc.)
* for x in expr:
* with expr as x:
* def x(...):
* class x:
* import x (or "import foo as x")
* from some_module import x (or "from some_module import foo as x")
取名称 x,看看:如果在 global
或 nonlocal
语句中声明,请将其保留在那里。否则,请将其添加到 local
声明中,紧跟在 global
和 nonlocal
之后。(python中没有local
关键字。这都是概念上的)。函数参数始终是本地的。这些语句中的名称应该是互斥的,就像它们引用的作用域一样。
这是第一遍。现在您可以坐下来阅读代码了。每当你看到一个变量名时,你都会在这三个语句上查找它 - global
、nonlocal
和我们虚构的local
。如果名字在那里 - 你知道它属于哪里。否则,在任何封闭函数上以相同的方式查找它,然后在全局命名空间中查找它。如果它不存在,它应该是一个内置的 - 或者一个错误。
这样做了update()
,你会得到:
def update():
local testing # not real python code
print "UPDATED"
testing = 2
嗯,这不是你的意思,对吧?
再举个例子,之前:
x=3
def print5():
for i in range(5):
print(x)
x += 1
后:
x=3
def print5():
local i, x
for i in range(5):
print(x) # oops. x is local but was not assigned!
x += 1
请注意,我描述的算法不是完整的。我省略了例外情况,这些例外情况仅隐藏了except
子句的名称; eval
和exec
;和from some_module import *
.
有关完整信息,请参阅文档:http://docs.python.org/2/reference/executionmodel.html#naming-and-binding