这里所说的可变对象一般是指list,dict等,首先看现象:

 
  1. >>> def function(data = []): 
  2. ... data.append(1
  3. ... print data 
  4. ... print type(data) 
  5. ...  
  6. >>> function() 
  7. [1
  8. <type 'list'
  9. >>> function() 
  10. [11
  11. <type 'list'
  12. >>> 
  13. >>> (function.func_defaults[0]) 
  14. [11
  15. >>> id(function.func_defaults[0]) 
  16. 3070981484L 
  17. >>> function() 
  18. [111
  19. <type 'list'
  20. >>> id(function.func_defaults[0]) 
  21. 3070981484L 

在每执行一次function函数,list就会增加一个值1,这是为什么呢?
通过 id(function.func_defaults[0])可以看出,每次调用完之后,其地址都未变。默认参数只在执行def语句的时候才被计算,即只在定义的时候发生。并且绑定到function上了,所以每次调用,可变参数都在原来的基础上进行操作,下面很好证明了在定义时调用:注意a.execute的调用:

 
  1. >>> def a(): 
  2. ... print "a executed" 
  3. ... return [] 
  4. ...  
  5. >>>  
  6. >>> def b(x=a()): 
  7. ... x.append(5
  8. ... print x 
  9. ...  
  10. a executed 
  11. >>> b() 
  12. [5
  13. >>> b() 
  14. [55
  15.  
  16. >>> def a(): 
  17. ... print "a executed" 
  18. ... return [] 
  19. ...  
  20. >>>  
  21. >>> def b(x=a()): 
  22. ... x.append(5
  23. ... print x 
  24. ...  
  25. a executed 
  26. >>> b() 
  27. [5
  28. >>> b() 
  29. [55

复制代码

怎么避免这种情况呢?使用None作为占位符,如下:
 

 
  1. >>> def instead_function(data=None): 
  2. ... if data is None
  3. ... data = [] 
  4. ... data.append(1
  5. ... print data 
  6. ...  
  7. >>> instead_function() 
  8. [1
  9. >>> instead_function() 
  10. [1