I am trying to inject constructor i.e. __init__
via super class, to avoid boilerplate code in __init__
in all my domain classes.
For example:
class Structure:
_fields = []
def __init__(self, *args):
if len(args) != len(self._fields):
raise TypeError("Wrong # arguments")
for name, value in zip(self._fields, args):
setattr(self, name, value)
class Stock(Structure):
_fields = ['name', 'shares', 'price']
stock = Stock("Amzn", "11", "2100")
print(stock.name)
The code above works fine when the constructor is limited to *args
. But there are some domain classes that takes **kwargs
too.
For example something like below:
class Structure:
_fields = []
def __init__(self, *args, **kwargs):
if (len(args) + len(kwargs)) != len(self._fields):
raise TypeError("Wrong # arguments")
for name, value in zip(self._fields, args):
setattr(self, name, value)
class Stock(Structure):
_fields = ['name', 'shares', 'price']
stock = Stock("Amzn", "11", price = "2100")
stock.price #AttributeError, stock object has no attribute 'price'
But obviously the code above won't set the kwargs, because I never touched kwargs in __init__
. Any idea how can I get this fixed?
How about checking if kwargs
exists?
>>> class SC:
...: _fields = []
...: def __init__(self, *args, **kwargs):
...: if (len(args) + len(kwargs)) != len(self._fields):
...: raise TypeError("Wrong # arguments")
...: for name, value in zip(self._fields, args):
...: setattr(self, name, value)
...: if kwargs:
...: self.__dict__.update(kwargs)
...:
>>> class SD2(SC):
... _fields = ['name', 'shares', 'price']
>>> i = SD2(name='Amzn', shares=1, price=2)
>>> i.name
'Amzn'
>>> i.shares
1
This works like this too:
>>>u= SD2('Amzn', shares=1, price=2)
>>>u.name
'Amzn'