可能重复:
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):
...
我的问题:
答案 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>