paw*_*que 56 python function defaults default-parameters
可能重复:
作为实例方法的结果的参数的默认值
虽然可以在python中将默认值设置为函数参数:
def my_function(param_one='default')
...
Run Code Online (Sandbox Code Playgroud)
似乎无法访问当前实例(self):
class MyClass(..):
def my_function(self, param_one=self.one_of_the_vars):
...
Run Code Online (Sandbox Code Playgroud)
我的问题:
Jon*_*nts 57
它被写成:
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
Run Code Online (Sandbox Code Playgroud)
而且我认为可以说在Python中永远不会发生由于self
在函数启动之前不存在的本质...(你不能在它自己的定义中引用它 - 就像其他一切一样)
例如:你做不到 d = {'x': 3, 'y': d['x'] * 5}
Ano*_*sse 22
它比你想象的要多得多.将默认值视为静态(=指向一个对象的常量引用)并存储在定义中的某个位置; 在方法定义时评估; 作为课程的一部分,而不是实例.因为它们是不变的,所以它们不能依赖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
Run Code Online (Sandbox Code Playgroud)
这将打印1 2 1 1 3
.
因为它的工作原理与之相同
default_s=[]
def add(item, s=default_s):
s.append(item)
Run Code Online (Sandbox Code Playgroud)
显然,如果你修改default_s
,它会保留这些修改.
有各种解决方法,包括
def add(item, s=None):
if not s: s = []
s.append(item)
Run Code Online (Sandbox Code Playgroud)
或者你可以这样做:
def add(self, item, s=None):
if not s: s = self.makeDefaultS()
s.append(item)
Run Code Online (Sandbox Code Playgroud)
然后该方法makeDefaultS
将有权访问self
.
另一种变化:
import types
def add(item, s=lambda self:[]):
if isinstance(s, types.FunctionType): s = s("example")
s.append(item)
Run Code Online (Sandbox Code Playgroud)
这里的默认值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 []
Run Code Online (Sandbox Code Playgroud)