Python全局/局部变量赋值问题

时间:2013-10-28 22:24:04

标签: python

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

testing = 1
print testing

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

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

test()

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

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

4 个答案:

答案 0 :(得分:3)

如果你要使用全局变量(一般来说这是一个坏主意,如果可能必须避免),你必须在每个修改testing的函数内部指示变量是全局变量,如下所示:

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

没有必要在global中明确使用test() - 我们只是在读取值,而我们在update()中更改它,但它作为剩余部分是有用的变量是全局定义的

def test():
    global testing # not mandatory, but useful as documentation
    new = testing
    print new

答案 1 :(得分:1)

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

答案 2 :(得分:1)

testingupdate()函数的本地变量。函数locals与模块全局变量完全分开。

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

如果要在函数中指定名称以将其视为全局静止,则需要显式覆盖Python并告诉它将名称视为全局:< / p>

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

您可以将global语句放在函数的任何位置,它将为整个函数创建特定名称global

答案 3 :(得分: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,并查看:如果在globalnonlocal语句中声明它,请将其留在那里。否则,请在localglobal之后将其添加到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