Monday, 19 September 2016

What is a clean, pythonic way to have multiple constructors in Python?




I can't find a definitive answer for this. As far as I know, you can't have multiple __init__ functions in a Python class. So how do I solve this problem?



Suppose I have a class called Cheese with the number_of_holes property. How can I have two ways of creating cheese objects...




  1. One that takes a number of holes like this: parmesan = Cheese(num_holes = 15)

  2. And one that takes no arguments and just randomizes the number_of_holes property: gouda = Cheese()




I can think of only one way to do this, but this seems clunky:



class Cheese():
def __init__(self, num_holes = 0):
if (num_holes == 0):
# randomize number_of_holes
else:
number_of_holes = num_holes



What do you say? Is there another way?


Answer



Actually None is much better for "magic" values:



class Cheese():
def __init__(self, num_holes = None):
if num_holes is None:
...



Now if you want complete freedom of adding more parameters:



class Cheese():
def __init__(self, *args, **kwargs):
#args -- tuple of anonymous arguments
#kwargs -- dictionary of named arguments
self.num_holes = kwargs.get('num_holes',random_holes())


To better explain the concept of *args and **kwargs (you can actually change these names):




def f(*args, **kwargs):
print 'args: ', args, ' kwargs: ', kwargs

>>> f('a')
args: ('a',) kwargs: {}
>>> f(ar='a')
args: () kwargs: {'ar': 'a'}
>>> f(1,2,param=3)
args: (1, 2) kwargs: {'param': 3}



http://docs.python.org/reference/expressions.html#calls


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...