在 Python 中,函数是数据,而类型是动态的。这意味着以下行是有效的 Python:
def func(x):
return x + 3
func = 3
func
现在是一个int。func
不再引用原始函数。最初是一个函数的事实func
与将来可以分配给它的数据类型没有任何关系。(这就是“动态类型”的意思。)
因此,由于没有静态类型,并且“函数”是有效的数据类型,Python 解释器区分函数和同名引用的数据是没有意义的。因此,在给定的范围内,没有办法使用相同的非限定变量名来表示两个不同的东西。
在您的特定情况下,如果您的xplus1
函数中的代码意味着什么,那将意味着“计算变量的值xplusy(x,1)
并将该值分配给变量xplusy
- 从而失去对函数 xplusy
的引用。” 但是,在函数范围内,解释器不允许您对该范围之外的变量进行赋值,因此它假定通过编写赋值语句,您正在引入一个新的局部变量xplusy
。但是,尚未定义局部变量,因此您调用它的尝试xplusy(x,1)
失败了。全局定义的函数不作为后备调用,因为同样,您不能让两个非限定名称相同并指向同一范围内的不同数据。
另一个演示“在一个范围内不重复变量名”规则的示例(实际上,我只是在尝试构建此答案时使用提示符时才发现的):
>>> def f1():
... a = xplusy(3,4)
... xplusy = 5
... print xplusy
...
>>> f1()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f1
UnboundLocalError: local variable 'xplusy' referenced before assignment
>>> def f1():
... a = xplusy(3,4)
... print a
...
>>> f1()
7
这表明它确实是范围,而不是需要唯一名称的语句。
编辑:这是一个非常酷的帖子,解释了这个和其他范围相关的行为: http: //me.veekun.com/blog/2011/04/24/gotcha-python-scoping-closures/