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
相关产品推荐
相关产品推荐

