gpt4 book ai didi

Python 惰性枚举

转载 作者:行者123 更新时间:2023-12-05 04:53:24 26 4
gpt4 key购买 nike

我正在尝试使用惰性求值创建一个 enum.Enum

根据文档:

An enumeration is a set of symbolic names (members) bound to unique, constant values. Within an enumeration, the members can be compared by identity, and the enumeration itself can be iterated over.

我会说我的情况仍然属于这个定义。这些值仍然是唯一且不变的,我只是希望它们只在必要时才被初始化。这可能是因为初始化很耗时,依赖于其他 Enum 成员,与其他 Enum 具有循环依赖性,或者(在我当前的情况下)因为初始化需要运行QGuiApplication,我希望我的模块在未运行时仍可导入(但保持特定枚举不可用)(当然还有其他方法可以解决此特定要求,但我会无论如何都喜欢实现这个 Enum 类)。

we are only supposed to subclass EnumMeta in rare cases ,我想通过子类化 Enum 本身来做到这一点:

class Lazy:
def __init__(self, value):
self.value = value

class LazyEnum(Enum):
def __getattribute__(self, name):
result = super().__getattribute__(name)
if name == 'value' and isinstance(result, Lazy):
result = self._lazy_init(result.value)
self.__setattr__(name, result)
return result

想法是将一些值标记为 Lazy 以便稍后初始化。但是,我的示例代码:

class MyEnum(LazyEnum):
X = Lazy('x')
Y = Lazy('y')
Z = 'z'

def _lazy_init(self, value):
print(f"Evaluating {value}")
return value * 2

print(MyEnum.X.value)
print(MyEnum.X)
print(MyEnum.X.value)

引发错误:

AttributeError: can't set attribute

我该如何解决这个问题?

最佳答案

我查看了 Enum 的源代码,我通过直接设置 _value_ 属性而不是 value 属性解决了这个问题。该解决方案对我来说有点老套,但它似乎有效:

from abc import ABCMeta, abstractmethod
from enum import Enum, EnumMeta


class AbstractEnumMeta(EnumMeta, ABCMeta):
pass


class Lazy:
def __init__(self, *lazy_init_arguments):
self.args = lazy_init_arguments


class LazyEnum(Enum, metaclass=AbstractEnumMeta):
def __getattribute__(self, name):
result = super().__getattribute__(name)
if name == 'value' and isinstance(result, Lazy):
result = self._lazy_init(*result.args)
setattr(self, '_value_', result)
return result

@classmethod
@abstractmethod
def _lazy_init(cls, *args):
return args


class MyEnum(LazyEnum):
X = Lazy('x')
Y = Lazy('y')
Z = 'z'

@classmethod
def _lazy_init(cls, value):
print(f"Lazy init of {value}")
return value * 2


>>> MyEnum.Z
MyEnum.Z
>>> MyEnum.Z.value
'z'
>>> MyEnum.X
MyEnum.X
>>> MyEnum.X.value
Lazy init of x
'xx'
>>> MyEnum.X.value
'xx'

关于Python 惰性枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66108148/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com