zoukankan      html  css  js  c++  java
  • python定义函数时默认参数注意事项

    如果在调用一个函数时,没有传递默认参数,则函数内的默认参数是对函数的默认参数属性__defaults__的引用,

          如

          def func(arg1=[]): arg1.append(2)

          调用func时如果没有传参,上面的arg1就是func.__defaults__[0]的引用

          没传递默认参数,会发生以下情况

          由于func.__defaults__[0]是可变类型,导致每一次调用func,arg1都会对func.__defaults__[0]进行操作(func.__defaults__[0].append(2),

          这样在有些情况下会导致逻辑出错的,例如

          def func(arg1=[]): if(arg1==[]): print'arg1 is empty' arg1.append(1) else: print'arg1 is not empty'print arg1 func() # arg1 is empty

          func() #arg1 is not empty [1] 

          第二次调用func的时候,并没有传递参数arg1,但是第一次调用时,函数内部已经修改了__defaults__

          这是为啥呢?为何第二次调用不重置arg1为[]?

          因为

          Python的默认参数只会在函数定义时被确定,而不是每次调用时重新确定,所以,一旦在函数中修改了默认参数,则再随后的调用中都会生效

          由于有这个特性,在定义函数时,如果默认参数使用可变的对象类型,如上例子,则很可能导致逻辑出错,

          所以,如不是特别需要,则不允许在函数内部对默认参数引用的func.__defaults__属性进行修改,如何能让一个对象不被修改?那就是在操作arg1前取消它对__defaults__的引用

          以上例子改动一下

          def func(arg1=[]): if(arg1==[]): print'arg1 is empty' arg1=[] arg1.append(1) else: print'arg1 is not empty'print arg1

          上例中,在用户没有传递默认参数arg1时,函数内部会给arg1变量重新赋值,让arg1去引用我们想用的对象[],这样arg1就不会修改func.__defaults__了

          如果是默认参数是有值的情况,可以这样操作

          def func(arg1=[1,2,3]): if(arg1==[1,2,3]): print'is [1,2,3]' arg1=[1,2,3] #重点是这里,取消arg1对__defaults__属性的引用,防止arg1修改__defaults__ arg1.append(1) else: print'not [1,2,3]'print arg1

          以上太啰嗦,下例模仿了python官方例子,使用不可变类型(例如None)作为默认参数,逻辑简洁,推荐使用

          def append_to(element, to=None): #默认参数to定义时为None,但函数逻辑中进行进一步重新赋值为想使用的默认值

          if to is None: to = [1,2,3] to.append(element) return to

          总结:

          防止默认参数修改函数的__defaults__,需要:

          1.定义默认参数时,最好使用不可变类型.

          2.如果默认参数一定要使用可变类型,那就在函数内部对默认参数重新赋值为可变类型的具体值.

  • 相关阅读:
    LeetCode Array Easy 414. Third Maximum Number
    LeetCode Linked List Medium 2. Add Two Numbers
    LeetCode Array Easy 283. Move Zeroes
    LeetCode Array Easy 268. Missing Number
    LeetCode Array Easy 219. Contains Duplicate II
    LeetCode Array Easy 217. Contains Duplicate
    LeetCode Array Easy 189. Rotate Array
    LeetCode Array Easy169. Majority Element
    LeetCode Array Medium 11. Container With Most Water
    LeetCode Array Easy 167. Two Sum II
  • 原文地址:https://www.cnblogs.com/wu-chao/p/9000581.html
Copyright © 2011-2022 走看看