下面一段代码演示了可变与不可变默认参数的区别,通过查看内存地址以及每次函数调用之后的默认参数的变化,可以看出两段代码为什么会产生不同的结果。
# -*- coding: cp936 -*-
# 上面一句是为了中文编码问题
# 默认值只被赋值一次。这使得当默认值是可变对象时会有所不同,比如列表、字典或者大多数类的实例。
# 例如,下面的函数在后续调用过程中会累积(前面)传给它的参数
def f(a,L=[]):
print('默认参数地址为:'+str(id(L)))
L.append(a)
print('改变后的参数地址为:'+str(id(L)))
return L
# 如果不想参数累积,可以如下定义
def f1(a,L1=None):
print('默认参数地址为:'+str(id(L1)))
if L1 is None:
L1=[]
L1.append(a)
print('改变后参数地址为:'+str(id(L1)))
return L1
# python中是引用赋值,list/dict均为可变类型,字符串/tuple为不可变类型
#下面可以看看这两段代码有什么不同
# f测试
print(f(1))
print('函数f的默认参数为'+str(f.__defaults__))
print(f(2))
print('函数f的默认参数为'+str(f.__defaults__))
print(f(3))
print('函数f的默认参数为'+str(f.__defaults__))
# f1测试
print(f1(1))
print('函数f1的默认参数为'+str(f1.__defaults__))
print(f1(2))
print('函数f1的默认参数为'+str(f1.__defaults__))
print(f1(3))
print('函数f1的默认参数为'+str(f1.__defaults__))
运行结果:
C:\Users\zzw922cn\Desktop>python 1.py
默认参数地址为:56716224
改变后的参数地址为:56716224
[1]
函数f的默认参数为([1],)
默认参数地址为:56716224
改变后的参数地址为:56716224
[1, 2]
函数f的默认参数为([1, 2],)
默认参数地址为:56716224
改变后的参数地址为:56716224
[1, 2, 3]
函数f的默认参数为([1, 2, 3],)
默认参数地址为:1525627488
改变后参数地址为:56738440
[1]
函数f1的默认参数为(None,)
默认参数地址为:1525627488
改变后参数地址为:56738440
[2]
函数f1的默认参数为(None,)
默认参数地址为:1525627488
改变后参数地址为:56738440
[3]
函数f1的默认参数为(None,)