引言
Python虽然没有C/C++的指针和各种数据类型转换,但不代表它没有一片坦途,对于初学者,再感叹Python的简单和强大之时,可能一不小心就掉到陷阱中去了。为了给后来者警示,特总结Python的各种陷阱,以起到“前车之覆,后车之鉴”的效果。
陷阱1:函数的默认参数只初始化一次
对于Python函数的默认参数,它只在定义之时执行一次。对于不可变数据类型,如string类型等,可能没什么影响。但对于 list, dictionary,大多数类的实例对象等而言,区别就很大了。如下所示:
def func1(a, b=[]):
b.append(a)
print b
func1(1)
func1(2)
func1(3)
class A(object):
def __init__(self):
print("Init A")
def func2(a, b=A()):
print(a)
func2(10)
func2(20)
func2(30)
输出结果:
[1]
[1, 2]
[1, 2, 3]
Init A
10
20
30
陷阱2:函数的默认参数表达式在定义范围内求值
Python函数的默认参数表达式,是在函数定义点,在其定义范围内求值的,而不是在函数调用之时求值。代码如下所示:
index = 100
def func(a = index):
print("a = %d"%(a))
index = 200
func()
输出结果:
a = 100
陷阱3:在循环中不要动态修改循环集合大小
在Python循环体中,如果动态修改循环集合的大小(比如增加或删除列表、字典的元素),会造成不可预料的结果。如下所示
>>> a = [3, 2, 2, 4]
>>> for i in a:
if i % 2 == 0:
a.remove(i)
>>> a
[3, 2]
一般会认为输出结果为 [3],其实在删除第二个元素“2”时,内部迭代器指示到了1位置&#