一、本地变量是静态检测的
python定义的在一个函数中进行分配的变量名是默认为本地变量的,它们存在于函数的作用域并只在函数运行时存在。python是静态检测python的本地变量的。看下面例子:
x = 99
def selector():
print x
selector()
结果为99。
这里,函数中的x被解析为模块中的x。但是如果在引用之后增加一个赋值语句,看看会发生什么。
x = 99
def selector():
print x
x = 88
selector()
结果为:
Traceback (most recent call last):
File "./test.py", line 13, in <module>
selector()
File "./test.py", line 11, in selector
print x
UnboundLocalError: local variable 'x' referenced before assignment
得到了一个未定义变量名的错误,其原因是微妙的。在交互模式下输入或从一个模块文件中导入时,python读入并编译这级代码。在编译时,python看到了对x的赋值语句,并且决定了x将会再函数中的任一地方都将是本地变量名。但是,当函数实际运行时,因为在print执行时赋值语句并没有发生,python告诉你正在使用一个未定义的变量名。根据其变量名规则,本地变量x是再其被赋值前使用的。实际上,任何在函数体内的赋值将会使其成为一个本地变量名。
二、默认和可变对象
默认参数是在def语句运行时被评估并保存的,而不是在这个函数调用时。从内部来讲,Python会将每一个默认参数保存成一个对象,附加在这个函数本身。
这也是通常我们所想要的:因为默认参数是在def时被评估的,所以必要的话,它能够从整个作用域内保存值,但是因为默认参数在调用之前保存了一个对象,必须对修改可变的默认参数十分小心。例如:
def saver(x=[]):
x.append(1)
print x
saver([2])
saver()
saver()
saver()
结果为:
[2, 1]
[1]
[1, 1]
[1, 1, 1]
三、函数没有重载
class C:
def meth(self, x):
print x
def meth(self, x, y, z):
print x, y, z
这样的代码是会执行的,但是def只是在类的作用域把对象赋值给变量名,这个方法函数的最后一个定义是唯一保留的(就好像x = 1,然后x = 2,结果x将是2)