Python—类方法中的默认值和<;代码>;自我</代码>;

Python—类方法中的默认值和<;代码>;自我</代码>;,python,class,constructor,Python,Class,Constructor,我有以下课程和方法: class Basis(object): def __init__(self, P = {'dimension': 1, 'generation':1}): self.P = P self.P['angle'] = np.pi/4 其中p是一个dict,它不包括“角度”,因此我在构造函数中设置它(角度现在是固定的,但将来可能会有一个用户定义的函数) 现在我有一个方法: def make_projection(self, dimension, angle =

我有以下课程和方法:

class Basis(object):

 def __init__(self, P = {'dimension': 1, 'generation':1}):

  self.P = P
  self.P['angle'] = np.pi/4
其中
p
是一个
dict
,它不包括
“角度”
,因此我在构造函数中设置它(角度现在是固定的,但将来可能会有一个用户定义的函数)

现在我有一个方法:

def make_projection(self, dimension, angle = np.pi/4):
 return (angle*3)
我想在这个函数中将
angle
的默认值设置为构造函数中定义的
self.p['angle']

我不想在函数的主代码中使用
self.P['angle']
,因为我可能会单独使用该方法,给它一个不同的角度

如果我只是这样做:
def make_projection(self,dimension,angle=self.p['angle']):
,它在
self
下面加下划线,我不明白为什么

--


这是允许我做的吗?

Python参数的默认值是在定义函数时计算的,而不是在调用函数时计算的

您需要执行以下操作:

def foo(self, x, y=None):
    if y is None:
        y = self.defval

这也是为什么在Python中使用可变默认值(例如字典)是一个危险的陷阱的原因;如果您更改默认值,您也将更改未来调用中的默认值。

首先,方法中关键字参数的默认值不能是可变对象,如
列表
dict
等。您可以了解原因

其次,在
def make_projection(self,dimension,angle=self.p['angle'])
中,
self
变量仍然没有定义,因此只能在方法体中获得
self.p

试试这个:

class Basis(object):

  def __init__(self, P=None):
    self.P = P or {'dimension': 1, 'generation':1}
    self.P['angle'] = np.pi/4

  def make_projection(self, dimension, angle=None):
    angle = angle if angle is not None else self.P['angle']  # we must compare to None, because angle can be 0.
    return angle*3
嗯,它们可以是可变对象,但它们不应该是因为新来者可能期望不同行为的暗示和违反直觉的行为。