简体   繁体   English

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

[英]How to initiallize subclass from superclass method?

I read online that the pythonic way of overloading constructors was to create class methods.我在网上读到重载构造函数的pythonic方法是创建 class 方法。 So I created a RectF class that can be initialized in one of two ways.所以我创建了一个RectF class ,它可以通过两种方式之一进行初始化。

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])

The init constructor takes an argument for each field, while the from_tuples method takes two tuples containing coordinates and size respectively. init 构造函数为每个字段接受一个参数,而from_tuples方法接受两个分别包含坐标和大小的元组。

However, when I go to initialize an instance of a subclass, using the from_tuples method, an exception is thrown.但是,当我在 go 初始化一个子类的实例时,使用from_tuples方法,抛出了异常。 Using super().__init__() works fine.使用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]

The code above is an example, and it works fine for now.上面的代码是一个示例,现在可以正常工作。 But for readability and maintainability's sake;但是为了可读性和可维护性; and just as a best practice, it would be useful to initialize objects using the least amount of arguments, especially if they get more complex over time.作为最佳实践,使用最少的 arguments 初始化对象会很有用,尤其是当它们随着时间的推移变得更加复杂时。

By the time __init__ gets called, the object has already been constructed, so it's too late to use from_tuples .__init__被调用时,object 已经构建好了,所以使用from_tuples为时已晚。

Don't use the number of arguments as the measure of simplicity.不要使用 arguments 的数量作为简单性的衡量标准。 Instead, think in terms of which methods can be used to implement others.相反,考虑哪些方法可以用来实现其他方法。 If you want tuples to be the fundamental building block of a rectangle, you can do that:如果您希望元组成为矩形的基本构建块,您可以这样做:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM