Python中函数参数的默认值

时间:2012-11-02 13:16:59

标签: python function defaults default-parameters

  

可能重复:
  default value of parameter as result of instance method

虽然可以在python中为函数参数设置默认值:

def my_function(param_one='default')
    ...

似乎无法访问当前实例(self):

class MyClass(..):

    def my_function(self, param_one=self.one_of_the_vars):
        ...

我的问题:

  • 我是否无法访问当前实例以在函数中设置默认参数?
  • 如果不可能:原因是什么,可以想象在未来的python版本中可以实现这一点?

4 个答案:

答案 0 :(得分:56)

它写成:

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

我认为可以肯定地说,由于self在函数启动之前不存在的性质,在Python中永远不会发生......(你不能在它自己的定义中引用它) - 像其他一切一样)

例如:您无法执行d = {'x': 3, 'y': d['x'] * 5}

答案 1 :(得分:21)

它比你想象的要多得多。将默认值视为 static (=指向一个对象的常量引用)并存储在定义中的某个位置;在方法定义时评估;作为的一部分,而不是实例。由于它们是不变的,它们不能依赖self

这是一个例子。这是违反直觉的,但实际上很有道理:

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

这将打印1 2 1 1 3

因为它的工作方式与

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

显然,如果您修改default_s,它会保留这些修改。

有各种解决方法,包括

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

或者你可以这样做:

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

然后方法makeDefaultS可以访问self

另一种变化:

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

此处s的默认值为工厂职能

您可以结合所有这些技巧:

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 []

答案 2 :(得分:3)

参数的默认值在“编译”中评估一次。显然你无法访问self。典型示例是list作为默认参数。如果在其中添加元素,则参数的默认值会更改!

解决方法是使用另一个默认参数,通常为None,然后检查并更新变量。

答案 3 :(得分:2)

你在这里做了多个错误的假设 - 首先,函数属于一个类而不属于一个实例,这意味着所涉及的实际函数对于类的任何两个实例都是相同的。其次,默认参数在编译时计算并且是常量(如在常量对象引用中 - 如果参数是可变对象,则可以更改它)。因此,您无法在默认参数中访问self,也永远无法访问。{/ p>