1

我是 python 新手,所以可能有一个简单的答案,但我什至不确定要搜索什么。这是一个简化的代码片段:

testing = 1
print testing

def update():
    print "UPDATED"
    testing = 2

update()
def test():
    new = testing
    print new

test()

我的期望是最后一次打印是“2”,但它是“1”。为什么会这样?

我需要这个,以便我可以检查某个变量的 init/update 的 unix 时间是否与特定函数(带有 while 循环)开始执行时相同。让我知道是否有更好的方法来实现这一目标。

4

4 回答 4

3

如果您要使用全局变量(这通常是一个坏主意,并且必须尽可能避免),您必须在每个修改testing变量是全局的函数内部指出,如下所示:

def update():
    global testing # mandatory: the variable is being modified
    print "UPDATED"
    testing = 2

没有必要显式使用globalin test()- 我们只是读取值,而我们正在更改它 in update(),但它作为变量是全局定义的余数很有用

def test():
    global testing # not mandatory, but useful as documentation
    new = testing
    print new
于 2013-10-28T22:25:40.547 回答
1

你必须在函数中声明你的变量全局(编写全局测试)。

于 2013-10-28T22:25:44.930 回答
1

testing是函数的局部变量update()。函数局部变量与模块全局变量完全分开。

如果您在范围内分配名称,Python 会将其标记为本地名称。testing被分配到 内update()new也分配给 in test(),但在那个函数testing不是。这使得testing, in test, 成为一个全球性的。这就是python如何让您找到在您的模块中声明或从另一个模块导入的内置函数、函数和其他对象。

如果要在函数中分配名称并将其视为全局变量,则需要显式覆盖 Python 并告诉它将该名称视为全局变量:

def update():
    print "UPDATED"
    global testing
    testing = 2

您可以将global语句放在函数中的任何位置,它将使该特定名称对整个函数全局。

于 2013-10-28T22:26:42.880 回答
0

我会尝试在 Oscar 和 Martijn 已经给出的好答案中添加一些内容。

当你在 python 中读取一个函数时,任何函数,你都必须阅读它两次。总是。

在第一遍中,您应该这样做:对于每个globalnonlocal声明语句,将它们(概念上)移动到函数的开头。

对于以下形式的每个陈述

* 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,看看:如果它是在globalornonlocal语句中声明的,就把它留在那里。否则,将其添加到local声明中,就在globaland之后nonlocal。(python中没有local关键字。这都是概念上的)。函数参数始终是本地的。这些语句中的名称应该是互斥的,就像它们引用的范围一样。

这是第一关。现在您可以坐下来阅读代码了。任何时候你看到一个变量名,你都会在这三个语句中查找它 - globalnonlocal以及我们想象中的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它只隐藏子句的名称;evalexec; 和from some_module import *

有关完整信息,请参阅文档:http ://docs.python.org/2/reference/executionmodel.html#naming-and-binding

于 2013-10-28T22:26:26.370 回答