如何正确定义访问子属性值的类方法?

问题描述 投票:0回答:2

在Python中,如何正确定义引用子类属性的父类的类方法?

from enum import Enum


class LabelledEnum(Enum):
    @classmethod
    def list_labels(cls):
        return list(l for c, l in cls.__labels.items())


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())
# expected output
# ["Label A", "Custom B", "Custom label for value C + another string"]

在上面的代码中,我希望

Test.list_labels()
能够正确打印出标签,但是因为
__labels
字典是用双下划线定义的,所以我无法正确访问它。

我想要双下划线的原因是为了确保在迭代枚举器时不会显示标签,例如list(Test) 不应显示包含标签的字典。

python enums python-class
2个回答
2
投票

如果您使用的是 Python >= 3.11,最好的选择是使用

enum.nonmember
单下划线:

In [8]: import enum
   ...:
   ...: class LabelledEnum(enum.Enum):
   ...:     @classmethod
   ...:     def list_labels(cls):
   ...:         return list(l for c, l in cls._labels.items())
   ...:
   ...:
   ...: class Test(LabelledEnum):
   ...:     A = 1
   ...:     B = 2
   ...:     C = 3
   ...:
   ...:     _labels = enum.nonmember({
   ...:         1: "Label A",
   ...:         2: "Custom B",
   ...:         3: "Custom label for value C + another string",
   ...:     })
   ...:

In [9]: list(Test)
Out[9]: [<Test.A: 1>, <Test.B: 2>, <Test.C: 3>]

In [10]: Test.list_labels()
Out[10]: ['Label A', 'Custom B', 'Custom label for value C + another string']

另一种方法是动态构建字符串,虽然它很笨重,但它会起作用(坦率地说,

enum
应该忽略下划线,而不是双下划线,但是唉):

@classmethod
def list_labels(cls):
    labels = getattr(cls, f"_{cls.__name__}__labels"
    return list(labels.values())

0
投票

你可以做一些非常丑陋的事情,比如:

getattribute(cls, f"_{cls.__name__}__labels", {})

我不确定它是否保证在所有情况下都有效。

from enum import Enum


class LabelledEnum(Enum):
    @classmethod
    def list_labels(cls):
        # account for private name mangling
        labels = getattribute(cls, f"_{cls.__name__}__labels", {})
        return list(l for c, l in labels.items())
© www.soinside.com 2019 - 2024. All rights reserved.