在带有签名验证的python中定义新类型时,如何避免重复代码

时间:2018-11-03 09:37:39

标签: python python-3.x optimization

我想知道是否有更好的解决方案在python中定义新类型。

我正在以这种方式编写新类的init方法:

class MyType (Base):

  def __init__(self, **kwargs):
    self.a1 = kwargs['a1']
    self.a2 = kwargs['a2']
    self.a3 = kwargs['a3']

但是我想写一个紧凑的编码风格:

class MyType (Base):

   __fields__ = ['a1', 'a2', 'a3']

以下解决方案vars(self).update(kwargs)self.__dict__.update(**kwargs)对我不满意,因为用户可以输入任何词典而不会出现错误消息。我需要检查用户是否插入以下签名(“ a1”,“ a2”,“ a3”,“ a4”,“ a5”)。 此外,用户应该能够通过传递“位置参数”或“ kay-value对参数”来使用对象。

我实现了以下代码,当缺少某些参数时,该代码能够发现KeyError。但是当添加额外的参数时,我不会出现任何错误:

class Structure:
    _fields = []
    def __init__(self, *args, **kwargs):
        print(self._fields, kwargs)
        for name in self._fields:
            setattr(self, name, kwargs[name])

class MyType (Structure):
    _fields = ['a1', 'a2', 'a3']

if __name__ == '__main__':
    m = MyType(**{'a1': 1}) # KeyError: 'a2'
    print(vars(m))      
    m = MyType(**{'a1': 1, 'a2': 3, 'a3': 4, 'a4': 5}) # no KeyError!!
    print(vars(m))

谢谢, 弗雷德里克

2 个答案:

答案 0 :(得分:3)

看看python3.7 data classes

从那里报价:

@dataclass
class InventoryItem:
    '''Class for keeping track of an item in inventory.'''
    name: str
    unit_price: float
    quantity_on_hand: int = 0
  

除其他事项外,还将添加如下内容的__init__()

def __init__(self, name: str, unit_price: float, quantity_on_hand: int=0):
    self.name = name
    self.unit_price = unit_price
    self.quantity_on_hand = quantity_on_hand

答案 1 :(得分:1)

您可以update中的dict实例__init__

>>> class MyType:
...:    def __init__(self, **kwargs):
...:        vars(self).update(kwargs)
...:        
>>> m = MyType(a1=1, a2=2, a3=3)
>>> vars(m)
>>> {'a1': 1, 'a2': 2, 'a3': 3}
>>> m.a1, m.a2, m.a3
>>> (1, 2, 3)