从__init__使用继承减少样板

问题描述 投票:0回答:1

我试图注入的构造,即通过__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__。任何想法,我怎么能得到这个固定的?

python python-internals
1个回答
2
投票

如何检查是否存在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'
© www.soinside.com 2019 - 2024. All rights reserved.