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



我是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

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

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

如果 Python 在作用域内分配名称,则会将其标记为本地名称。 testing被分配到 update() 内。 newtest()中也被赋值,但在那个函数中testing不是。这使得testing,在test,是一个全球性的。这就是 python 让你找到在你的模块中声明或从另一个模块导入的内置、函数和其他对象的方式。

如果你想赋值到函数中的名字,并且仍然把它当作一个全局的你需要显式覆盖Python,并告诉它把这个名字当作一个全局的:

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

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

我会尝试在奥斯卡和马蒂恩已经给出的好答案中添加一些东西。

当你在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 语句中声明,请将其保留在那里。否则,请将其添加到 local 声明中,紧跟在 globalnonlocal 之后。(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

最新更新