简化数据结构的初始化

  • 1、不想写太多烦人的__init __() 函数,可以在一个基类中写一个公用的__init__()函数


  1. # -*- coding: utf-8 -*-
  2. import math
  3. class Structure1(object):
  4. _fields = []
  5. def __init__(self, *args):
  6. if len(args) != len(self._fields):
  7. raise TypeError("Expected {} arguments".format(len(self._fields)))
  8. for name, value in zip(self._fields, args):
  9. setattr(self, name, value)
  10. class Stock(Structure1):
  11. _fields = ['name', 'shares', 'price']
  12. class Point(Structure1):
  13. _fields = ['x', 'y']
  14. class Circle(Structure1):
  15. _fields = ['radius']
  16. def area(self):
  17. return math.pi * self.radius ** 2
  18. s = Stock("ACME", 50, 91.1)
  19. p = Point(3, 5)
  20. c = Circle(4.5)
  21. print(s.__dict__)
  22. print(p.__dict__)
  23. print(c.__dict__)
  24. 运行结果:
  25. {'name': 'ACME', 'shares': 50, 'price': 91.1}
  26. {'x': 3, 'y': 5}
  27. {'radius': 4.5}
  • 2、还能将不在fields 中的名称加入到属性中去
  1. # -*- coding: utf-8 -*-
  2. class Structure2(object):
  3. _fields = []
  4. def __init__(self,*args,**kwargs):
  5. if len(args) != len(self._fields):
  6. raise TypeError("Expected {} arguments".format(len(self._fields)))
  7. for name,value in zip(self._fields,args):
  8. setattr(self,name,value)
  9. extra_args = kwargs.keys() - self._fields
  10. for name in extra_args:
  11. setattr(self,name,kwargs.pop(name))
  12. if kwargs:
  13. raise TypeError("Duplicate values for {}".format(','.join(kwargs)))
  14. class Stock(Structure2):
  15. _fields = ["name","shares","price"]
  16. if __name__ == '__main__':
  17. s1 = Stock("ACME",50,91.1)
  18. s2 = Stock("ACME",50,91.1,date="2018/01/08")
  19. print(s1.__dict__)
  20. print(s2.__dict__)
  21. 运行结果:
  22. {'name': 'ACME', 'shares': 50, 'price': 91.1}
  23. {'name': 'ACME', 'shares': 50, 'price': 91.1, 'date': '2018/01/08'}

当需要使用大量很小的数据结构类的时候,相比手工一个个定义__init__() 方法,使用这种方式可以大大简化代码
详情可以参考《Python Cookbook》第三版第八章