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

Python:如何正确定义父类classmethod以访问子类的名称修饰属性?

解决父类类方法访问子类双下划线属性的问题

首先,你用双下划线__labels的目的是避免它被枚举迭代包含,但其实Enum元类会自动跳过以下划线开头的属性,不将其作为枚举成员,所以单下划线_labels就足够满足需求,同时还能让父类的类方法直接访问。

最优解决方案:改用单下划线属性

修改代码如下,既保证list(Test)不会包含标签字典,又能让父类正确获取标签列表:

from enum import Enum

class LabelledEnum(Enum):
    @classmethod
    def list_labels(cls):
        # 直接通过cls访问子类的_labels属性,返回所有标签值的列表
        return list(cls._labels.values())

class Test(LabelledEnum):
    A = 1
    B = 2
    C = 3

    _labels = {
        1: "Label A",
        2: "Custom B",
        3: "Custom label for value C + another string",
    }

print(Test.list_labels())
# 输出:["Label A", "Custom B", "Custom label for value C + another string"]
print(list(Test))
# 输出:[<Test.A: 1>, <Test.B: 2>, <Test.C: 3>],不包含标签属性

若坚持使用双下划线属性的解决方案

双下划线属性会被Python自动做名称修饰(变成_类名__属性名),父类可以通过构造修饰后的属性名来访问:

from enum import Enum

class LabelledEnum(Enum):
    @classmethod
    def list_labels(cls):
        # 构造子类中被修饰后的__labels属性名
        labelled_attr = f"_{cls.__name__}__labels"
        # 获取属性并返回标签列表
        labels = getattr(cls, labelled_attr)
        return list(labels.values())

class Test(LabelledEnum):
    A = 1
    B = 2
    C = 3

    __labels = {
        1: "Label A",
        2: "Custom B",
        3: "Custom label for value C + another string",
    }

print(Test.list_labels())
# 输出符合预期

这种方法依赖Python的名称修饰规则,可读性不如单下划线方案,因此更推荐第一种。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 00:50:28