Python optional parameters

前端 未结 3 687
别那么骄傲
别那么骄傲 2020-12-29 22:53

Guys, I just started python recently and get confused with the optional parameters, say I have the program like this:

class B:
   pass

class A:
    def __in         


        
相关标签:
3条回答
  • 2020-12-29 23:31

    Yes; default parameters are evaluated only at the time when the function is defined.

    One possible solution would be to have the parameter be a class rather than an instance, a la

    def foo(blah, klass = B):
        b = klass()
        # etc
    
    0 讨论(0)
  • 2020-12-29 23:37

    You need to understand how default values work in order to use them effectively.

    Functions are objects. As such, they have attributes. So, if I create this function:

    >>> def f(x, y=[]):
            y.append(x)
            return y
    

    I've created an object. Here are its attributes:

    >>> dir(f)
    ['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__',   
    '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__',    
    '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', 
    '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
    'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 
    'func_name']
    

    One of them is func_defaults. That sounds promising, what's in there?

    >>> f.func_defaults
    ([],)
    

    That's a tuple that contains the function's default values. If a default value is an object, the tuple contains an instance of that object.

    This leads to some fairly counterintuitive behavior if you're thinking that f adds an item to a list, returning a list containing only that item if no list is provided:

    >>> f(1)
    [1]
    >>> f(2)
    [1, 2]
    

    But if you know that the default value is an object instance that's stored in one of the function's attributes, it's much less counterintuitive:

    >>> x = f(3)
    >>> y = f(4)
    >>> x == y
    True
    >>> x
    [1, 2, 3, 4]
    >>> x.append(5)
    >>> f(6)
    [1, 2, 3, 4, 5, 6]
    

    Knowing this, it's clear that if you want a default value of a function's parameter to be a new list (or any new object), you can't simply stash an instance of the object in func_defaults. You have to create a new one every time the function is called:

    >>>def g(x, y=None):
           if y==None:
               y = []
           y.append(x)
           return y
    
    0 讨论(0)
  • 2020-12-29 23:41

    you need to do the following:

    class A:
        def __init__(self, builds=None):
            if builds is None:
                builds = B()
            self.builds = builds
    

    it's a very wide-spread error, using mutable parameters as a default arguments. there are plenty of dupes probably on SO.

    0 讨论(0)
提交回复
热议问题