Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Don';不理解为什么会发生UnboundLocalError(闭包)_Python_Scope_Closures_Global Variables - Fatal编程技术网

Python Don';不理解为什么会发生UnboundLocalError(闭包)

Python Don';不理解为什么会发生UnboundLocalError(闭包),python,scope,closures,global-variables,Python,Scope,Closures,Global Variables,我做错了什么 counter = 0 def increment(): counter += 1 increment() 上面的代码抛出一个UnboundLocalError要修改函数中的全局变量,必须使用global关键字 当你尝试在没有线的情况下这样做时 global counter 在增量的定义中,创建了一个名为counter的局部变量,以避免弄乱整个程序可能依赖的计数器变量 请注意,修改变量时只需使用全局变量;您可以从增量中读取计数器,而不需要全局语句。您需要使用,以便修改全

我做错了什么

counter = 0

def increment():
  counter += 1

increment()

上面的代码抛出一个
UnboundLocalError

要修改函数中的全局变量,必须使用global关键字

当你尝试在没有线的情况下这样做时

global counter
在增量的定义中,创建了一个名为counter的局部变量,以避免弄乱整个程序可能依赖的计数器变量

请注意,修改变量时只需使用全局变量;您可以从增量中读取计数器,而不需要全局语句。

您需要使用,以便修改全局变量计数器,而不是局部变量:

counter = 0

def increment():
  global counter
  counter += 1

increment()
如果定义了
计数器
的封闭范围不是全局范围,那么在Python3.x上可以使用。在Python2.x上的相同情况下,您将无法重新分配给非本地名称
计数器
,因此需要使
计数器
可变并修改它:

counter = [0]

def increment():
  counter[0] += 1

increment()
print counter[0]  # prints '1'
试试这个

counter = 0

def increment():
  global counter
  counter += 1

increment()

Python不是纯粹的词汇范围

见此:


这是:

Python没有变量声明,因此它必须找出变量本身的定义。它是通过一个简单的规则来实现的:如果函数中有一个变量赋值,那么该变量被认为是局部变量。因此,这条线

counter += 1
隐式地使
计数器
成为
increment()
的本地计数器。但是,如果尝试执行这一行,将尝试在赋值之前读取局部变量
计数器的值,从而导致错误


如果
计数器
是一个全局变量,则关键字将有帮助。如果
increment()

闭包将封闭环境中的值绑定到本地环境中的名称。然后,本地环境可以使用绑定值,甚至可以将该名称重新分配给其他名称,但它不能修改封闭环境中的绑定

在本例中,您试图将
计数器
视为局部变量,而不是绑定值。请注意,此代码绑定在封闭环境中指定的
x
值,工作正常:

>>> x = 1

>>> def f():
>>>  return x

>>> f()
1

为了回答主题行中的问题,*是的,Python中有闭包,只是它们只应用于函数内部,而且(在Python2.x中)它们是只读的;不能将名称重新绑定到其他对象(尽管如果对象是可变的,可以修改其内容)。在Python3.x中,可以使用关键字修改闭包变量

def incrementer():
    counter = 0
    def increment():
        nonlocal counter
        counter += 1
        return counter
    return increment

increment = incrementer()

increment()   # 1
increment()   # 2

*这个问题最初是关于Python中的闭包的。

代码抛出
UnboundLocalError
的原因已经在其他答案中得到了很好的解释

但在我看来,你似乎在试图建立一个类似于

那你为什么不试试,看看是否适合你的情况:

>>> from itertools import count
>>> counter = count(0)
>>> counter
count(0)
>>> next(counter)
0
>>> counter
count(1)
>>> next(counter)
1
>>> counter
count(2)

python 3文档中有一个让我吃惊的注释,我在文件顶部声明了一个变量,我可以在函数中读取该变量,但要写入我在文件顶部声明的变量,我必须使用全局变量。更深入的解释:。不仅赋值可以绑定名称,导入也可以绑定名称,因此您还可以从使用无界导入名称的语句中获取
UnboundLocalError
。示例:
def foo():bar=deepcopy({'a':1});从复制导入深度复制;返回条
,然后从复制导入到复制;foo()
。如果从copy import deepcopy
中删除本地导入
,则调用将成功。此问题及其当前标记为重复的问题正在中讨论。此处的许多答案都表示使用
全局
,尽管这样做有效,当存在其他选项时,通常不建议使用可修改的globals。@ZeroPiraeus 2012年提出的问题不能与2016年提出的问题重复。。。相反,较新的版本是重复的。@dsh.@juanpa.arrivillaga尽管一般问题是结束并更新非本地的绑定。完全局部变量也可能发生UnboundLocalError,但它们是一个不同的问题(使用不同的解决方案)。虽然此链接可以回答问题,但最好在此处包含答案的基本部分,并提供链接以供参考。如果链接页面发生更改,则仅链接的答案可能无效-