You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何super()可修改父类字典类变量却无法递增数值类变量?

问题

运行以下Python代码片段时出现异常:

class Magical_SportsPerson:
    database = {}
    playerNo = 0
    def __init__(self,name,team,jerseyNo):
        self.name = name
        self.team = team
        self.jerseyNo = jerseyNo
    
    def __str__(self):
        return "Name:{}\nTeam:{}\nJerseyNo:{}".format(self.name,self.team, self.jerseyNo)
    
class Quidditch_Player(Magical_SportsPerson):
    def __init__(self,name,team,jerseyNo,goals = None,retirement_date = "Not yet retired"):
        super().__init__(name,team,jerseyNo)
        super().playerNo += 1 # 此处报错
        self.goals = goals
        self.retirement_date = retirement_date

        # 创建玩家ID格式:playerNo + 名字首字母 + 姓氏首字母 + 球衣号
        self.playerID = str(super().playerNo) + self.name[0] + self.name[self.name.index(" ") + 1] + str(self.jerseyNo)

        # 玩家详情列表
        self.playerDetails = [self.name, self.team, self.jerseyNo, self.goals, self.retirement_date]
        
        # 添加到数据库
        super().database[self.playerID] = self.playerDetails

    def __str__(self):
        details = Magical_SportsPerson.__str__(self) + "\nGoals:{}".format(self.goals) + "\nRetirement Date:{}".format(self.retirement_date)
        return details
    
    @classmethod
    def createPlayer(cls,name,team,jerseyNo,goals = None ,retirement_date = "Not yet retired"):
        return cls(name,team,jerseyNo,goals,retirement_date)

创建实例时:

p1 = Quidditch_Player("Harry Potter","Gryffindor", 8, 523)
print("------Details of the player------")
print(p1)

抛出错误:AttributeError: 'super' object has no attribute 'playerNo'。但改用Magical_SportsPerson.playerNo += 1就能正常运行,同时super().database[self.playerID] = self.playerDetails可以正常修改父类的database类变量。同为父类Magical_SportsPerson的类变量,为何super()对两者的操作结果不同?

解答

核心原因是赋值操作(+=属于赋值类操作)和取值/修改容器内部元素的操作,对super()对象的行为影响完全不同:

  • 针对super().database[self.playerID] = self.playerDetails:
    这不是给super()对象赋值属性,而是先通过super()找到父类的database字典对象,再修改这个字典的内部键值对。super()在这里仅负责查找父类属性,最终操作的是找到的字典实例本身,不会触发属性赋值逻辑,因此能正常工作。

  • 针对super().playerNo += 1:
    +=本质是playerNo = playerNo + 1,属于属性赋值操作。当对super()对象进行属性赋值时,Python不会将值赋给父类的类变量,反而会尝试在当前类(Quidditch_Player)或实例上创建新属性。但在赋值前的取值阶段,super()找不到playerNo(super()本身不存储属性,仅作为查找链),于是直接抛出AttributeError。

而直接使用Magical_SportsPerson.playerNo += 1时,是明确指定修改父类的类变量,绕过了super()的属性查找与赋值逻辑,因此能正确修改父类的playerNo。

补充说明:如果只是读取super().playerNo(比如print(super().playerNo)),是可以正常获取父类类变量值的,但一旦涉及赋值操作,super()的行为就会改变——赋值会绑定到当前上下文(当前类或实例),而非父类。

内容的提问来源于stack exchange,提问作者Arif Hamim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 17:52:50