如何从超类方法初始化子类?

时间:2019-10-07 20:54:20

标签: python inheritance methods initialization superclass

我在网上阅读到,重载构造函数的pythonic方法是创建类方法。因此,我创建了一个RectF类,可以用以下两种方法之一进行初始化。

class RectF:
    def __init__(self, x: float, y: float, w, h):
        self.x: float = x
        self.y: float = y
        self.width = w
        self.height = h

    @classmethod
    def from_tuples(cls, pos: tuple, size: tuple):
        return cls(pos[0], pos[1], size[0], size[1])

init构造函数为每个字段接受一个参数,而from_tuples方法接受两个分别包含坐标和大小的元组。

但是,当我使用from_tuples方法初始化子类的实例时,会引发异常。使用super().__init__()很好。

class Entity(RectF):
    def __init__(self, pos: tuple, size: tuple, vel: tuple):
        super().__init__(pos[0], pos[1], size[0], size[1])

        # I would like to initialize the superclass using the from_tuples class method.
        # super().from_tuples(pos, size)
        # This throws the following exception: __init__() takes 4 positional arguments but 5 were given

        self.vel_x = vel[0]
        self.vel_y = vel[1]

上面的代码是一个示例,现在可以正常工作。但是出于可读性和可维护性的考虑;并且作为最佳实践,使用最少数量的参数初始化对象将很有用,尤其是随着时间的推移它们变得越来越复杂。

1 个答案:

答案 0 :(得分:2)

__init__被调用时,该对象已经被构造,因此使用from_tuples为时已晚。

请勿将参数数量用作简化程度的度量。相反,请考虑可以使用哪些方法来实现其他方法。如果希望元组成为矩形的基本构建块,则可以执行以下操作:

class RectF:
    def __init__(self, pos: tuple, size: tuple):
        self.x: float = pos[0]
        self.y: float = pos[1]
        self.width = size[0]
        self.height = size[1]

    # No good name for this method comes to mind
    @classmethod
    def from_separate_values(cls, x, y, w, h):
        return cls((x, y), (w, h))


class Entity(RectF):
    def __init__(self, pos: tuple, size: tuple, vel: tuple):
        super().__init__(pos, size)
        self.vel_x = vel[0]
        self.vel_y = vel[1]

    @classmethod
    def from_separate_values(cls, x, y, w, h, vx, vy):
        rv = super().from_separate_values(x, y, w, h)
        rv.vel_x = vx
        rv.vel_y = vy
        return rv