继承的 __init__() 函数未按预期工作
Inherited __init__() function not working as intended
我在 Python 上使用 pygame
库开发游戏。我基本上定义了一个 Character
class,Knight
class 和 Enemy
class 将从中继承函数。由于两个子 class 使用相同的初始化函数,我在父 class 下定义了 __init__()
函数。但是,我不完全理解它是如何工作的,并且出现以下错误:
TypeError: __init__() takes 1 positional argument but 3 were given
这是我的代码:
class Character():
def __init__(self, img, hitbox, vel, pos_x, pos_y):
self.img = img
self.hitbox = hitbox
self.vel = vel
self.pos_x = pos_x
self.pos_y = pos_y
def draw(self):
if self.right:
pygame.transform.flip(self.img, True, False)
win.blit(self.img, (self.pos_x, self.pos_y))
class Knight(Character):
def __init__(self):
Character.__init__(self)
def move(self):
if self.right:
if self.x + self.vel < win_width:
self.x += self.vel
if self.left:
if self.x - self.vel > 0:
self.x -= self.vel
main_plr = Knight("img", (19, 20), 5, 30, 20)
快速修复:只需从 Knight
.
中删除 __init__
方法
错误出现是因为你用 6 创建了一个 Knight
对象
参数 (self, "img", (19, 20), 5, 30, 20
) 而 __init__
方法只接受一个 (self
).
因此,如果您的 Knight
对象没有任何附加属性
与 Character
个对象相比,删除
__init__
方法。现在如果你想让你的骑士拥有武器,因为
例如,你将不得不做这样的事情:
class Knight(Character):
def __init__(self, img, hitbox, vel, pos_x, pos_y, weapon):
super().__init__(img, hitbox, vel, pos_x, pos_y)
self.weapon = weapon
k = Knight("img", (19, 20), 5, 30, 20, "sword")
[编辑]
此外,正如@Matiiss 所建议的,您可以使用 *args
来避免
在 Knight.__init__
中重复 Character.__init__
的所有参数。
除了简洁之外,还有一个优点是您不必修改
Knight
如果您向 Character
对象添加属性。
class Knight(Character):
def __init__(self, *args, weapon):
super().__init__(*args)
self.weapon = weapon
k = Knight("img", (19, 20), 5, 30, 20, weapon="sword")
但现在的缺点是你必须指定 weapon
weapon="the-weapon"
,因为它现在是关键字参数(放置
在 *args
).
之后
正如您看到的错误所说,您的 Knight
构造函数不接受这些参数;如果您要使用那种继承的方法扩展,class 和 subclass 方法需要具有匹配的参数签名。最好使用 super()
来引用超级 class 而不是明确命名它。
最简单的处理方法是使用*args
和**kwargs
,将subclass方法不需要的参数简洁地传递给super[=19] =]方法,即
class Character():
def __init__(self, img, hitbox, vel, pos_x, pos_y):
self.img = img
self.hitbox = hitbox
self.vel = vel
self.pos_x = pos_x
self.pos_y = pos_y
class Knight(Character):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def move(self):
if self.right:
if self.x + self.vel < win_width:
self.x += self.vel
if self.left:
if self.x - self.vel > 0:
self.x -= self.vel
我在 Python 上使用 pygame
库开发游戏。我基本上定义了一个 Character
class,Knight
class 和 Enemy
class 将从中继承函数。由于两个子 class 使用相同的初始化函数,我在父 class 下定义了 __init__()
函数。但是,我不完全理解它是如何工作的,并且出现以下错误:
TypeError: __init__() takes 1 positional argument but 3 were given
这是我的代码:
class Character():
def __init__(self, img, hitbox, vel, pos_x, pos_y):
self.img = img
self.hitbox = hitbox
self.vel = vel
self.pos_x = pos_x
self.pos_y = pos_y
def draw(self):
if self.right:
pygame.transform.flip(self.img, True, False)
win.blit(self.img, (self.pos_x, self.pos_y))
class Knight(Character):
def __init__(self):
Character.__init__(self)
def move(self):
if self.right:
if self.x + self.vel < win_width:
self.x += self.vel
if self.left:
if self.x - self.vel > 0:
self.x -= self.vel
main_plr = Knight("img", (19, 20), 5, 30, 20)
快速修复:只需从 Knight
.
__init__
方法
错误出现是因为你用 6 创建了一个 Knight
对象
参数 (self, "img", (19, 20), 5, 30, 20
) 而 __init__
方法只接受一个 (self
).
因此,如果您的 Knight
对象没有任何附加属性
与 Character
个对象相比,删除
__init__
方法。现在如果你想让你的骑士拥有武器,因为
例如,你将不得不做这样的事情:
class Knight(Character):
def __init__(self, img, hitbox, vel, pos_x, pos_y, weapon):
super().__init__(img, hitbox, vel, pos_x, pos_y)
self.weapon = weapon
k = Knight("img", (19, 20), 5, 30, 20, "sword")
[编辑]
此外,正如@Matiiss 所建议的,您可以使用 *args
来避免
在 Knight.__init__
中重复 Character.__init__
的所有参数。
除了简洁之外,还有一个优点是您不必修改
Knight
如果您向 Character
对象添加属性。
class Knight(Character):
def __init__(self, *args, weapon):
super().__init__(*args)
self.weapon = weapon
k = Knight("img", (19, 20), 5, 30, 20, weapon="sword")
但现在的缺点是你必须指定 weapon
weapon="the-weapon"
,因为它现在是关键字参数(放置
在 *args
).
正如您看到的错误所说,您的 Knight
构造函数不接受这些参数;如果您要使用那种继承的方法扩展,class 和 subclass 方法需要具有匹配的参数签名。最好使用 super()
来引用超级 class 而不是明确命名它。
最简单的处理方法是使用*args
和**kwargs
,将subclass方法不需要的参数简洁地传递给super[=19] =]方法,即
class Character():
def __init__(self, img, hitbox, vel, pos_x, pos_y):
self.img = img
self.hitbox = hitbox
self.vel = vel
self.pos_x = pos_x
self.pos_y = pos_y
class Knight(Character):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def move(self):
if self.right:
if self.x + self.vel < win_width:
self.x += self.vel
if self.left:
if self.x - self.vel > 0:
self.x -= self.vel