Default Values for function parameters in Python [duplicate]

偶尔善良 提交于 2019-11-27 17:57:16

It's written as:

def my_function(self, param_one=None): # Or custom sentinel if None is vaild
    if param_one is None:
        param_one = self.one_of_the_vars

And I think it's safe to say that will never happen in Python due to the nature that self doesn't really exist until the function starts... (you can't reference it, in its own definition - like everything else)

For example: you can't do d = {'x': 3, 'y': d['x'] * 5}

There is much more to it than you think. Consider the defaults to be static (=constant reference pointing to one object) and stored somewhere in the definition; evaluated at method definition time; as part of the class, not the instance. As they are constant, they cannot depend on self.

Here is an example. It is counterintuitive, but actually makes perfect sense:

def add(item, s=[]):
    s.append(item)
    print len(s)

add(1)     # 1
add(1)     # 2
add(1, []) # 1
add(1, []) # 1
add(1)     # 3

This will print 1 2 1 1 3.

Because it works the same way as

default_s=[]
def add(item, s=default_s):
    s.append(item)

Obviously, if you modify default_s, it retains these modifications.

There are various workarounds, including

def add(item, s=None):
    if not s: s = []
    s.append(item)

or you could do this:

def add(self, item, s=None):
    if not s: s = self.makeDefaultS()
    s.append(item)

Then the method makeDefaultS will have access to self.

Another variation:

import types
def add(item, s=lambda self:[]):
    if isinstance(s, types.FunctionType): s = s("example")
    s.append(item)

here the default value of s is a factory function.

You can combine all these techniques:

class Foo:
    import types
    def add(self, item, s=Foo.defaultFactory):
        if isinstance(s, types.FunctionType): s = s(self)
        s.append(item)

    def defaultFactory(self):
        """ Can be overridden in a subclass, too!"""
        return []

Default value for parameters are evaluated at "compilation", once. So obviously you can't access self. The classic example is list as default parameter. If you add elements into it, the default value for the parameter changes!

The workaround is to use another default parameter, typically None, and then check and update the variable.

There are multiple false assumptions you're making here - First, function belong to a class and not to an instance, meaning the actual function involved is the same for any two instances of a class. Second, default parameters are evaluated at compile time and are constant (as in, a constant object reference - if the parameter is a mutable object you can change it). Thus you cannot access self in a default parameter and will never be able to.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!