8.11 简化数据结构的初始化

问题

你写了很多仅仅用作数据结构的类,不想写太多烦人的 __init__() 函数

解决方案

可以在一个基类中写一个公用的 __init__() 函数:

import math

class Structure1:
    # Class variable that specifies expected fields
    _fields = []

    def __init__(self, *args):
        if len(args) != len(self._fields):
            raise TypeError('Expected {} arguments'.format(len(self._fields)))
        # Set the arguments
        for name, value in zip(self._fields, args):
            setattr(self, name, value)

然后使你的类继承自这个基类:

使用这些类的示例:

如果还想支持关键字参数,可以将关键字参数设置为实例属性:

你还能将不在 _fields 中的名称加入到属性中去:

讨论

想直接更新实例字典,就像下面这样:

尽管这也可以正常工作,但是当定义子类的时候问题就来了。 当一个子类定义了 __slots__ 或者通过property(或描述器)来包装某个属性, 那么直接访问实例字典就不起作用了。我们上面使用 setattr() 会显得更通用些,因为它也适用于子类情况。

这种方法唯一不好的地方就是对某些IDE而言,在显示帮助函数时可能不太友好。可以参考9.16小节来强制在 __init__() 方法中指定参数的类型签名。

Last updated

Was this helpful?