当枚举成员不存在时返回默认会员

发布于 2025-02-01 11:49:13 字数 543 浏览 2 评论 0原文

我有一个枚举,我希望当成员内部不存在默认会员。例如:

class MyEnum(enum.Enum):
    A = 12
    B = 24
    CUSTOM = 1


print(MyEnum.UNKNOWN) # Should print MyEnum.CUSTOM

我知道我可以使用类似的元素:

class MyMeta(enum.EnumMeta):
    def __getitem__(cls, name):
        try:
            return super().__getitem__(name)
        except KeyError as error:
            return cls.CUSTOM

class MyEnum(enum.Enum,metaclass=MyMeta):
    ...

但是,只有在使用myenum ['unknown']访问枚举时,这似乎是有效的。有没有办法涵盖在不存在成员时访问枚举成员的两种方法?

I have an Enum where I would like a default member to be returned when a member does not exist inside of it. For example:

class MyEnum(enum.Enum):
    A = 12
    B = 24
    CUSTOM = 1


print(MyEnum.UNKNOWN) # Should print MyEnum.CUSTOM

I know I can use a metaclass like so:

class MyMeta(enum.EnumMeta):
    def __getitem__(cls, name):
        try:
            return super().__getitem__(name)
        except KeyError as error:
            return cls.CUSTOM

class MyEnum(enum.Enum,metaclass=MyMeta):
    ...

But that appears to only work if I access the Enum using MyEnum['UNKNOWN']. Is there a way that covers both methods of accessing members of an enum when the member doesn't exist?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

上课铃就是安魂曲 2025-02-08 11:49:13

__ getAttr __的定义添加到Metaclass:

class MyMeta(enum.EnumMeta):
    def __getitem__(cls, name):
        try:
            return super().__getitem__(name)
        except KeyError as error:
            return cls.CUSTOM
    
    def __getattr__(cls, name):
        try:
            return super().__getattr__(name)
        except AttributeError as error:
            return cls.CUSTOM

然后,您的代码将输出:

MyEnum.CUSTOM

Add a definition for __getattr__ to the metaclass:

class MyMeta(enum.EnumMeta):
    def __getitem__(cls, name):
        try:
            return super().__getitem__(name)
        except KeyError as error:
            return cls.CUSTOM
    
    def __getattr__(cls, name):
        try:
            return super().__getattr__(name)
        except AttributeError as error:
            return cls.CUSTOM

Then, your code will output:

MyEnum.CUSTOM
千里故人稀 2025-02-08 11:49:13

编译 @brokentbenchmark 的答案和这个答案,以及一些知识,让我们使默认枚举成员一个参数:

class EnumWithDefaultMeta(enum.EnumMeta):

    @classmethod
    def __prepare__(metacls, name, bases, **kwargs):
        return super().__prepare__(name, bases)

    def __new__(metacls, name, bases, namespace, **kwargs):
        newclass = super().__new__(metacls, name, bases, namespace)
        newclass._missing_ = classmethod(metacls._missing_)
        return newclass

    def __init__(cls, name, bases, namespace, default='UNKNOWN'):
        cls.default = default
        super().__init__(name, bases, namespace)

    def __getitem__(cls, name):
        try:
            return super().__getitem__(name)
        except KeyError:
            return super().__getitem__(cls.default)

    def __getattr__(cls, name):
        try:
            # noinspection PyUnresolvedReferences
            return super().__getattr__(name)
        except AttributeError:
            # noinspection PyUnresolvedReferences
            return super().__getattr__(cls.default)

    def _missing_(cls, _value):
        return super().__getitem__(cls.default)

class MyEnum(enum.Enum, metaclass=EnumWithDefaultMeta, default='CUSTOM'):
    A = 12
    B = 24
    CUSTOM = 1

输出:

MyEnum(123)
>>> <MyEnum.CUSTOM: 1>
MyEnum.Test
>>> <MyEnum.CUSTOM: 1>
MyEnum['Test']
>>> <MyEnum.CUSTOM: 1>

Compiling the answer of @BrokenBenchmark, and this answer, and a bit of knowledge, let's make default enum member a parameter:

class EnumWithDefaultMeta(enum.EnumMeta):

    @classmethod
    def __prepare__(metacls, name, bases, **kwargs):
        return super().__prepare__(name, bases)

    def __new__(metacls, name, bases, namespace, **kwargs):
        newclass = super().__new__(metacls, name, bases, namespace)
        newclass._missing_ = classmethod(metacls._missing_)
        return newclass

    def __init__(cls, name, bases, namespace, default='UNKNOWN'):
        cls.default = default
        super().__init__(name, bases, namespace)

    def __getitem__(cls, name):
        try:
            return super().__getitem__(name)
        except KeyError:
            return super().__getitem__(cls.default)

    def __getattr__(cls, name):
        try:
            # noinspection PyUnresolvedReferences
            return super().__getattr__(name)
        except AttributeError:
            # noinspection PyUnresolvedReferences
            return super().__getattr__(cls.default)

    def _missing_(cls, _value):
        return super().__getitem__(cls.default)

class MyEnum(enum.Enum, metaclass=EnumWithDefaultMeta, default='CUSTOM'):
    A = 12
    B = 24
    CUSTOM = 1

Output:

MyEnum(123)
>>> <MyEnum.CUSTOM: 1>
MyEnum.Test
>>> <MyEnum.CUSTOM: 1>
MyEnum['Test']
>>> <MyEnum.CUSTOM: 1>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文