我正在使用Python 2.7.12和numpy 1.12.0并观察以下行为。这是预期的吗?我认为" a "属于范围w.r.t" f2 "在这两种情况下如何访问" a "与访问 a [ind,:] 不同?
import numpy as np
def f1():
a = np.zeros((1, 10))
def f2():
print locals()
v = [0] * 10
v[3] = 1
a += v
f2()
def f11():
a = np.zeros((1, 10))
def f2():
print locals()
v = [0] * 10
v[3] = 1
a[0,:] = v
f2()
结果:
>>> f11()
{'a': array([[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])}
>>> f1()
{}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in f1
File "<stdin>", line 7, in f2
UnboundLocalError: local variable 'a' referenced before assignment
>>>
答案 0 :(得分:1)
在您的第一个示例中,您使用了扩充分配:
a += v
这使a
成为本地变量;所有绑定操作(包括赋值)都会使变量成为局部变量。这是在编译时确定的。请参阅Python执行模型的Naming and binding section:
如果名称绑定在块中,则它是该块的局部变量。
[...]
以下构造绑定名称: [...] 目标,如果在分配 [...] 中发生,则为标识符。
a
是一个标识符的目标。
因为a
被认为是本地的,在绑定之前尝试读取引用,将引发UnboundLocal
异常。扩充分配必须先读取a
才能分配回a
,因此会出现异常。
您的第二个示例未绑定到a
中任何位置的f2
;分配给a
的切片不会改变名称a
本身。您已分配到a[0,:]
;这不是一个标识符,而是一个切片。
您可以将a += v
替换为np.add(a, v, out=a)
来使第一个示例正常工作。