Python中的小坑

来源:互联网 发布:linux命令退出编辑 编辑:程序博客网 时间:2024/05/21 20:25
  1. 类的继承、MRO
class A(object):    x=1class B(A):    pass        class C(A):    passprint A.x,B.x,C.xB.x=2print A.x,B.x,C.xA.x=3print A.x,B.x,C.x'''1 1 11 2 13 2 3'''

在Python语言中,类变量是以字典的形式进行处理的,并且遵循方法解析顺序(Method Resolution Order,MRO)。在上面的代码中,由于类C中并没有x这个属性,解释器将会查找它的基类(base class,尽管Python支持多重继承,但是在这个例子中,C的基类只有A)。而B改写以后具有自己的x属性,所以运行如上

  1. list切片
l=['a','b']print l[3:]'''[]'''

看一下源码就知道了

def get_slice(a, beg, end, delta=1):    # 数组切片get方式    if delta == 0: raise ValueError("slice step cannot be 0")    # 将负数下标转化一下    if beg < 0: beg += len(a)    if end < 0: end += len(a)    # 转换后不在合法范围内,则返回空列表    if beg < 0 and end < 0 or beg >= len(a) and end >= len(a): return []    # ……
  1. 闭包
def multipliers():    return [lambda x:i*x for i in range(4)]print [m(2) for m in multipliers()]'''[6, 6, 6, 6]'''

由于Python的迟绑定(late binding)机制,闭包中内部函数的值只有在被调用时才会进行查询,因此multipliers函数返回的lambda函数被调用时,会在附近的作用域中查询变量i的值,而在create_multipliers生成返回数组之后,整数i的值是4,不会再改变,因此返回数组中每个匿名函数实际上都是:

lambda x: 3*x

解决办法是将临时值也保存在匿名函数的作用域内,在声明匿名函数时就查询变量的值:

def multipliers():    return [lambda x,i=i:i*x for i in range(4)]print [m(2) for m in multipliers()]'''[0, 2, 4, 6]'''
  1. 函数默认值
def foo(x,l=[]):    l.append(x)    return lprint foo(1)print foo(2,l=[])print foo(3)'''[1][2][1, 3]'''

python中函数的默认值只会被执行一次,也就是定义该函数的时候。(和静态变量一样,静态变量初始化也是被执行一次)。Python可以通过函数的默认值来实现静态变量的功能。再看一点代码:

i = 5def f(arg=i):    print argi = 6f()'''5'''

也是上述原因。

相关概念:
1.可变对象和不可变对象
2.闭包及变量绑定

原创粉丝点击