Python OOP:初始化BasketballPlayer对象为何需传入player_name参数?
我是一名学生开发者,正在为即将到来的测试备考。做继承与多态练习题时代码实现了预期效果,但搞不懂为什么初始化BasketballPlayer对象时必须传player_name参数,去掉就会抛出TypeError: Player.__init__() missing 1 required positional argument: 'player_name'。
Player.py 代码
class Player: def __init__(self, player_name): self.player_name = player_name def get_player_name(self): return self.player_name def set_player_name(self, player_name): self.player_name = player_name class BasketballPlayer(Player): positions = ['Guard', 'Forward', 'Center'] def __init__(self, player_name): super().__init__(player_name) self.player_position = None def get_player_position(self): return self.player_position def set_player_position(self, player_position): self.player_position = player_position if self.player_position not in BasketballPlayer.positions: print("Invalid position for basketball player.") self.player_position = "" def __str__(self): return f"{self.get_player_name()} playing as a {self.player_position}"
测试程序代码
from Player import * List_of_players = [] team_name = str(input("Please enter the basketball team name: ")) for i in range(5): player_name = str(input("Please enter player name: ")) player_position = str(input("Please enter the basketball player's position: ")) BasketBallPlayer_obj = BasketballPlayer(player_name) BasketBallPlayer_obj.set_player_position(player_position) BasketBallPlayer_obj.set_player_name(player_name) List_of_players.append(BasketBallPlayer_obj) print(f"Team {team_name} consists of the following players: ") for i in range(len(List_of_players)): print(List_of_players[i])
原因解析
1. 父类构造函数的参数要求
父类Player的__init__方法必须接收player_name参数,用来初始化实例属性self.player_name。子类BasketballPlayer的__init__方法里通过super().__init__(player_name)主动调用了父类的构造函数,这就要求必须提供player_name参数给父类使用,否则父类的构造函数会因为缺少必要参数报错。
2. 子类构造函数的参数定义
你编写的BasketballPlayer类的__init__方法签名是def __init__(self, player_name):,这明确规定了创建该类对象时,必须传入player_name参数(self是Python自动传入的实例引用,不需要手动传)。如果去掉这个参数,子类的__init__就没有player_name值可以传递给父类的构造函数,必然触发参数缺失的错误。
额外优化提示
测试代码中,创建BasketBallPlayer_obj后调用set_player_name(player_name)是冗余操作——因为初始化对象时已经将player_name传给父类,完成了self.player_name的赋值,完全可以删掉这一行代码。
内容的提问来源于stack exchange,提问作者Joshua Long

