Уменьшите шаблон с __init__, используя Наследование - PullRequest
0 голосов
/ 05 февраля 2019

Я пытаюсь внедрить конструктор, т.е. __init__ через суперкласс, чтобы избежать шаблонного кода в __init__ во всех моих классах домена.

Например:

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)

Приведенный выше код прекрасно работает, когда конструктор ограничен *args.Но есть некоторые доменные классы, которые тоже принимают **kwargs.

Например, что-то вроде ниже:

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'

Но очевидно, что приведенный выше код не установит kwargs, потому что я никогда не касался kwargs в __init__.Любая идея, как я могу это исправить?

1 Ответ

0 голосов
/ 05 февраля 2019

Как насчет проверки, существует ли kwargs?

>>> 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

Это работает так же:

>>>u= SD2('Amzn', shares=1, price=2)                                                                                                                                                             
>>>u.name                                                                                                                                                                                
'Amzn'
...