函数的默认值


01.函数的默认值的注意事项:

  • 函数在定义的时候,如果有默认形参,则该值会被保存下来,通过对象的__defaults__属性查看,比如:
def foo(x=[1, 2, 3, 4, 5]):
    print(x)

print(foo.__defaults__)
  • __defaults__属性以元组方式存储参数的默认值,其目的是为了保存参数的顺序。
  • __defaults__元组中元素的顺序不允许修改。
  • 函数在执行的时候,如果没有传参,则会向__defaults__获取保存的默认值,比如:
def foo(x=[]):
    x.append(1)
    print(x)

foo()
foo()
  • 第一次执行foo()时,由于没有传参,因此获取x在__defaults__中的值为[],插入元素后为[1]。
  • 第二次执行foo()时,由于没有传参,因此获取x在__defaults__中的值为[1],插入元素后为[1, 1]。
    • __defaults__中的值也是内存中的引用,因此要区分可变与不可变的对象;此处列表未可变对象,因此起内存引用不变。
    • __defaults__中如x=1,则为不可变对象,不管函数中对x做什么操作,在__defaults__中其值始终为1。
  • 如果函数有keyword-only形参,则其值保存在__kwdefaults__中。


02.设置函数默认值之后,按需改变的方法:

  • 使用浅拷贝,不改变__defaults__:
def foo(x=[]):
    x = x.copy()
    x.append(1)
    print(x)

foo()
print(foo.__defaults__)
foo()
print(foo.__defaults__)
  • 使用影子拷贝创建一个新的对象,永远不能改变传入的参数。
  • 使用不可变类型默认值:
def foo(x=None):
    if x is None:
        x = []
    x.append(1)
    print(x)

foo() 
print(foo.__defaults__)
foo([5, 10])
print(foo.__defaults__)
  • 如果使用缺省值,则创建一个新列表;如果传入一个列表,则修改该列表。
  • 许多函数定义都使用None作为默认参数,这是一种惯用的方法。
文档更新时间: 2020-09-20 17:19   作者:闻骏