如何从超类方法初始化子类?
How to initiallize subclass from superclass method?
我在网上看到重载构造函数的 pythonic 方法是创建 class 方法。所以我创建了一个 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])
init 构造函数为每个字段接受一个参数,而 from_tuples
方法接受两个分别包含坐标和大小的元组。
但是,当我使用from_tuples
方法去初始化一个subclass的实例时,抛出了异常。使用 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]
上面的代码是一个示例,目前可以正常运行。但是为了可读性和可维护性;作为最佳实践,使用最少的参数初始化对象会很有用,尤其是当它们随着时间的推移变得越来越复杂时。
当__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
我在网上看到重载构造函数的 pythonic 方法是创建 class 方法。所以我创建了一个 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])
init 构造函数为每个字段接受一个参数,而 from_tuples
方法接受两个分别包含坐标和大小的元组。
但是,当我使用from_tuples
方法去初始化一个subclass的实例时,抛出了异常。使用 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]
上面的代码是一个示例,目前可以正常运行。但是为了可读性和可维护性;作为最佳实践,使用最少的参数初始化对象会很有用,尤其是当它们随着时间的推移变得越来越复杂时。
当__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