我正在通过一个项目学习Python,并且遇到了子类化的问题。根据我读到的所有内容,该过程非常简单,但是从子类调用基类的方法会导致属性未找到错误。
我的代码示例包括基类(Player)、子类(Roster)的相关部分以及对基类和子类的设置和调用。我缺少什么?如果确实不需要的话,是否有必要在子类中创建一个 init 方法?
主要脚本:
from battleship.player import Player, Roster
player=Player()
roster=Roster()
player.register()
roster.load_other_players()
课程:
class Player:
def __init__(self):
....
self.getOtherPlayers = {}
def register(self):
...
return
def get_other_players (self):
return self.getOtherPlayers
def gameFlow(self):
if self.currentFlow != undefined:
self.currentFlow+=1
else:
self.currentFlow = 0
def setMove(self, m):
return move.setMove(m);
class Roster(Player):
def __init__(self):
super().__init__()
def load_other_players(self):
print("Roster!!!")
print("Other players: ", super.get_other_players())
返回:
Roster!!!
Traceback (most recent call last):
File "player.py", line 23, in <module>
roster.load_other_players()
File "/home/jspooner/projects/battleship/BotPlayer/battleship/player.py", line 152, in load_other_players
print("Other players: ", super.get_other_players())
AttributeError: type object 'super' has no attribute 'get_other_players'
编辑 如果将来有人引用这个问题,我的实际问题是一个设计问题,我创建了基类的实例以及子类的实例。结果,我有 2 个相关类的实例,它们彼此没有关联。
为了解决这个问题,我交换了层次结构,使 Roster 是父类,Player 是子类。我的 main 创建了一个 Player 实例,它自然地创建了一个相关的 Roster 类。
解决您的主要问题:
super
不是有效实体,它将是函数 super()
。或者,由于 Roster
继承自 Player
,因此 self.get_other_players()
也是一种可接受的引用方式,因为所有超类的属性都被合并为子类。
如果不需要,则无需显式创建 __init__
,但如果要执行某些初始化,则有必要。值得阅读 THIS 答案,以获取有关 __init__
实际情况以及为什么有必要的更深入信息。
回答一个您没有问过的问题:Python 在某些方面与其他一些语言不同,最值得注意的是不需要使用 getter 和 setter。只需直接访问
super().get_other_players()
属性,而不是 getOtherPlayers
或等效项。它更优雅,代码行更少,并且在维护代码时更容易阅读/调试(它更“Pythonic”)
这很简单,你忘了 super 中的 () 。您应该像这样调用该函数:
super().get_other_players()
而不是super.get_other_players()
,因为 super 是一个函数。
另外,如果你只是不需要的话,绝对没有必要在子类中使用构造函数(在子类中定义
__init__()
方法)。