本文参考自伯乐在线:http://blog.jobbole.com/42706/
1.用可变值作为默认值
记住一点,在Python里,函数的默认值在函数定义的时候实例化的,而不是在调用的时候。
比如下面这个函数,numbers参数初始化为空列表,那么每次调用的时候都会将9加入到列表后面:
def foo(numbers=[]): numbers.append(9) print numbers结果:
>>> foo() # first time, like before
[9]
>>> foo() # second time
[9, 9]
>>> foo() # third time...
[9, 9, 9]
>>> foo() # WHAT IS THIS BLACK MAGIC?!
[9, 9, 9, 9]
再看一个更加明显的例子:
def print_now(now=time.time()): print now这个函数输出当前时间戳,这个时间戳不是每次调用时的时间戳,而是该函数定义时被解释器解释时候的时间戳!
>>> print_now() 1373121487.91 >>> print_now() 1373121487.91 >>> print_now() 1373121487.91
2作用域
尽量不要用全局变量。这可能会带来诸多麻烦。
bar = 42 def foo(): print bar上面这段代码的输出结果是42,因为函数内部的bar是全局变量。再看下面这段代码:
>>> bar = 42 ... def foo(): ... bar = 0 ... foo() ... print bar 42foo中的bar其实是一个局部变量,你并没有改变全局变量的值。再看下面这段代码:
bar = 42 def foo(): print bar bar = 0
你本来想打印全局变量bar之后再创建一个局部变量bar,但事实上,报错了!
提示局部变量bar在没有赋值前就被引用了。这是因为python是解释性语言,当解释器执行到def foo():函数声明时,会静态的从这个函数作用域获取信息。当解释到bar=0这一行时会把bar加入局部变量列表(是解释到这一行,不是执行到这一行,所以此时局部变量bar并没有被赋值),但当执行到print bar时,局部变量bar没有赋值,所以就报错了。
如果想让程序按照原先的想法执行,那么应该要加上global关键字声明。
事实上,这些错误我们有时候很清楚,但就是写的时候容易忽略这一点。尤其是在和其他语言混合编程的时候很容易混淆。