Python - default value in class method and s

2020-04-21 03:07发布

问题:

I have the following class and method:

class Basis(object):

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

  self.P = P
  self.P['angle'] = np.pi/4

where P is a dict that does not include the 'angle', hence why I am setting it within the constructor (the angle is something fixed for now, but I might have it a user-defined funciton in the future).

Now I have a method:

def make_projection(self, dimension, angle = np.pi/4):
 return (angle*3)

and I would like to set the default value of angle in this function to the self.P['angle'] defined in the constructor.
I do not want to use the self.P['angle'] within the main code of the function, as I might use the method on its own giving it a different angle.

If I just do: def make_projection(self, dimension, angle = self.P['angle']): , it underlines both self and I do not understand why.

--

Is this something I am allowed to do?

回答1:

First of all, the defaults for keywords arguments in methods can't be mutable objects, like list, dict, etc. Here you can read why.

Secondly, in def make_projection(self, dimension, angle = self.P['angle']) the self variable is still not defined, so you can get self.P only in method's body.

Try this:

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


回答2:

Python default values for arguments are evaluated when the function is defined, not when the function is called.

You need to do something like:

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

This is also the reason for which having a mutable default (e.g. a dictionary) is a dangerous trap in Python; if you change the value that was given by default you're also changing what will be the default in future calls.