链接:
压缩列表的命令不熟悉,注意下
其中常见错误1中
>>> def foo(bar=[]): # bar是可选参数,如果没有指明的话,默认值是[]
... bar.append("baz") # 但是这行可是有问题的,走着瞧…
... return bar
>>> foo()
["baz"]
>>> foo()
["baz", "baz"]
>>> foo()
["baz", "baz", "baz"]
>>> def foo(bar=None):
... if bar is None: # 或者用 if not bar:
... bar = []
... bar.append("baz")
... return bar
...
>>> foo()
["baz"]
>>> foo()
["baz"]
>>> foo()
["baz"]
链接中给出解释是函数参数的默认值,仅仅在该函数被定义的时候被赋值一次,当调用foo()的时候会继续使用bar最早初始化的那个列表。这种解释在这个问题上没有说服力,第一个foo仅仅是因为没有对函数默认参数做特殊处理。
def foo(bar=[]):
if bar == []: # 对默认参数做特殊判断
bar = []
bar.append('baz')
return bar
print(foo())
print(foo())
print(foo())
['baz']
['baz']
['baz']
def foo(bar=[]):
# if bar == []: # 没有默认参数处理,bar相当于不是本地变量,bar相当于是全局变量,使用最近一
# 次的赋值
# bar = []
print(bar)
bar.append('baz')
return bar
print(foo())
print(foo())
print(foo())
[]
['baz']
['baz']
['baz', 'baz']
['baz', 'baz']
['baz', 'baz', 'baz']
常见错误4:误解python作用域规则
x = 10
def foo():
x += 1
print(x)
foo()
UnboundLocalError: local variable 'x' referenced before assignment
lst1 = [1, 2, 3]
def foo1():
lst1.append(5)
foo1()
lst2 = [1, 2, 3]
def foo2():
lst2 += [5]
foo2()
UnboundLocalError: local variable 'lst2' referenced before assignment
python作用域按照从小到大的范围依次是LEGB,在一个作用域里面给一个变量赋值的时候,Python自动认为这个变量是这个作用域的本地变量。所有foo()中x += 1将x作为本地变量后,并没有在foo()中定义x,同理foo2()函数也是犯了这个错误。
常见错误10:错误的使用__del__方法
# mod.py
import foo
class Bar(object):
def __del__(self):
foo.cleanup(self.myhandle)
#another_mod.py
import mod
mybar = mod.Bar() # 执行将后出现AttributeError
当python解释器关闭时,模块所有的全局变量会被置为None,当__del__被调用时,foo已经被置为None了.使用atexit.register可以解决这个问题。如此,当程序结束的时候,注册的处理程序会在解释器关闭之前处理