0

I'm a newbie to Python and I'm looking for a way to write a class with many optional properties, that can be initialized in a single code line.

What I've found so far is the approach of optional parameters to the init method which can be assigned by name:

class MyClass():
    def __init__(self, param1=None, param2=None, param3=None, param4=None):
        self.param1 = param1
        self.param2 = param2
        self.param3 = param3
        self.param4 = param4

And the initialization can look like:

o1 = MyClass(param2="someVal", param4="someOtherVal")

This approach seems fine, plus I think an IDE like IntelliJ will be able to supply some code completion in this style.

However, I wonder if this is the right approach in case I will create a complex class hierarchy. Let's say that MyClass will inherit from MyBaseClass and MyOtherClass and I wish to initialize all the properties from all the classes through the init method of MyClass(or some other way?).

What's the best way to accomplish this, hopefully with still helping the IDE to be able to provide code completion?

Thanks for the help.

AntonKam
  • 163
  • 11

2 Answers2

0

A class with so many optional arguments in its constructor is probably a "code smell" and a redesign is in order. I suggest writing some parameter group classes:

class ParamSetA:
    def __init__(param2="someVal", param4="someOtherVal"):
    self.param2 = param2
    self.param4 = param4

class ParamSetB:
    def __init__(param3, param4):
    self.param3 = param3
    self.param4 = param4

class MyClass():
    def __init__(self, params):
        self.params = params

Now it is obvious how to pass the parameters to other related classes: just pass the entire object which encapsulates one valid set of parameters.

This also makes validation easier: it is more difficult to construct MyClass with a nonsensical set of parameters (e.g. mutually exclusive parameters, or related parameters).

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • Hi John. this is not relevant for my case, I have many properties and all of them are optional, there is no logical grouping for them. I disagree that this is a design smell, a class represents an entity, and an entity may have many attributes, so allowing to initialize any number of them from the constructor to allow the user to initialize my class in a single line makes sense. In C# such a class can easily be initialized using the initialization list syntax, and what I'm searching here is something similar in Python. – AntonKam Jan 30 '18 at 06:40
0

How about this?

class Base:
    def __init__(self, param1=None, param2=None, param3=None, param4=None):

class Derived(Base):
    def __init__(self, param1=None, param2=None, param3=None, param4=None):
        super().__init__(**locals())

Ref: Get a list/tuple/dict of the arguments passed to a function? - you may need to use inspect.getargspec() as well.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436