以下程序会询问nonlocal
UnboundLocalError: local variable 'balance' referenced before assignment
个关键字
>>> def make_withdraw(balance):
"""Return a withdraw function with a starting balance."""
def withdraw(amount):
if amount > balance:
return 'Insufficient funds'
balance = balance - amount
return balance
return withdraw
>>> withdraw = make_withdraw(101)
>>> withdraw(25)
但是,如果内部函数shift
在赋值为lst
之前引用temp = lst[0]
,则程序下方不会出现此类错误。
def shift_left(lst, n):
"""Shifts the lst over by n indices
>>> lst = [1, 2, 3, 4, 5]
>>> shift_left(lst, 2)
>>> lst
[3, 4, 5, 1, 2]
"""
assert (n > 0), "n should be non-negative integer"
def shift(ntimes):
if ntimes == 0:
return
else:
temp = lst[0]
for index in range(len(lst) - 1):
lst[index] = lst[index + 1]
lst[index + 1] = temp
return shift(ntimes-1)
return shift(n)
我如何理解/比较这两种情况?
答案 0 :(得分:1)
您永远不会分配到lst
,只会分配到lst[index]
。这两个概念并不完全相同。
该行:
lst = some_other_value
将重新绑定名称lst
以指向另一个对象。这一行:
lst[index] = some_other_value
通过将该序列中的特定索引绑定到其他内容来更改名称lst
引用的对象。名称lst
本身永远不会被更改,因此这里没有关于该名称所属范围的歧义。
在Python范围界定中,只对名称本身的绑定操作计数。绑定操作不仅仅是(直接)分配,还包括import
,except .. as
的函数参数,函数和类定义,with .. as
语句和目标以及for ... in
中的目标循环。如果名称在给定范围内绑定,则将其视为 local ,在所有其他情况下,Python在父作用域中查找名称,最外层作用域为global
。
subscriptions 的分配(使用[...]
)在此上下文中不是绑定操作。
请参阅Python执行模型文档的Naming and binding section以及 Short Description of the Scoping Rules? 帖子。