我有这样的代码(简化):
def outer():
    ctr = 0
    def inner():
        ctr += 1
    inner()
但是ctr会导致错误:
Traceback (most recent call last):
  File "foo.py", line 9, in <module>
    outer()
  File "foo.py", line 7, in outer
    inner()
  File "foo.py", line 5, in inner
    ctr += 1
UnboundLocalError: local variable 'ctr' referenced before assignment
我怎样才能解决这个问题?我认为嵌套的范围可以让我这样做.我试过'全球',但它仍然无效.
Ale*_*lli 42
如果您使用的是Python 3,则可以使用该nonlocal语句启用非本地名称的重新绑定:
def outer():
    ctr = 0
    def inner():
        nonlocal ctr
        ctr += 1
    inner()
如果您使用的是Python 2,那么nonlocal您需要在没有裸名重绑定的情况下执行递增(通过将计数器保留为某个裸名的项或属性,而不是作为裸名本身).例如:
...
ctr = [0]
def inner():
    ctr[0] += 1
...
当然可以ctr[0]在ctr其他任何地方使用裸露的地方使用.
Ara*_*Fey 12
每当将值分配给函数内部的变量时,python都会将该变量视为该函数的局部变量。(是否执行赋值都没有关系-只要函数中存在赋值,分配给的变量将被视为该函数的局部变量。)由于该语句ctr += 1包括对ctrpython 的赋值认为ctr对inner功能而言是本地的。因此,它甚至从不尝试查看在中ctr定义的变量的值outer。python看到的本质上是这样的:
def inner():
    ctr = ctr + 1
我认为我们都可以同意该代码会导致错误,因为ctr在定义之前就已对其进行了访问。
(另请参阅文档或此问题,以获取有关python如何确定变量范围的更多详细信息。)
Python 3引入了nonlocalstatement,它的工作方式与该global语句非常相似,但是让我们可以访问周围函数的变量(而不是全局变量)。只需nonlocal ctr在inner函数顶部添加,问题就会消失:
def outer():
    ctr = 0
    def inner():
        nonlocal ctr
        ctr += 1
    inner()
由于该nonlocal语句在python 2中不存在,因此我们必须要有技巧。有两种简单的解决方法:
删除所有分配给 ctr
由于python只考虑ctr了局部变量,因为对该变量进行了赋值,所以如果我们删除对name的所有赋值,问题就会消失ctr。但是,如何在不赋值的情况下更改变量的值呢?简单:我们将变量包装在一个可变对象中,例如列表。然后,我们无需修改名称即可修改该列表ctr:
def outer():
    ctr = [0]
    def inner():
        ctr[0] += 1
    inner()
ctr作为参数传递给inner
def outer():
    ctr = 0
    def inner(ctr):
        ctr += 1
        return ctr
    ctr = inner(ctr)
来自http://www.devshed.com/c/a/Python/Nested-Functions-in-Python/1/
嵌套函数体中的代码可以访问(但不重新绑定)外部函数的局部变量,也称为嵌套函数的自由变量.
所以,你需要传递ctr给inner明确.
| 归档时间: | 
 | 
| 查看次数: | 6811 次 | 
| 最近记录: |