英文:
Any fancy way to unwind Enum classes in python?
问题
I understand your request. Here's the translated code:
我目前正在编写一个包,其中包含多个`Enum`类,并希望直接从包名称而不是从类本身访问它们的符号名称,就像OpenCV一样。是否有任何方法来定义这些类但仍然可以直接从包中访问它们的符号名称,或者我应该直接将它们硬编码到包的`__init__.py`中?
目前我处于这个状态:
```python
from enum import Enum
class enum_class1(Enum):
class1_sym1: int = 0
class1_sym2: int = 1
class1_sym3: int = 2
class enum_class2(Enum):
class2_sym1: int = 0
class2_sym2: int = 1
class2_sym3: int = 2
我目前正在做的事情:
import mypackage as p
state = p.enum_class2.class2_sym1
我更想要的是:
import mypackage as p
state = p.class2_sym1
Please note that I've corrected a typo in your code (`class_2_sim1` to `class2_sym1`) in the "What I am currently doing" section to match your desired output.
<details>
<summary>英文:</summary>
I am currently coding a package that contains several `Enum` classes and would like to use the symbolic names directly from the package name, not from the classes themselves, as OpenCV does. Is there anyway to define the classes but still accessing their symbolic names directly from the package or shall I directly hardcode them in the package's `__init__.py` ?
For now I am currently in this state:
```python
from enum import Enum
class enum_class1(Enum):
class1_sym1: int = 0
class1_sym2: int = 1
class1_sym3: int = 2
class enum_class2(Enum):
class2_sym1: int = 0
class2_sym2: int = 1
class2_sym3: int = 2
What I am currently doing :
import mypackage as p
state = p.enum_class2.class_2_sim1
What I would like to rather do :
import mypackage as p
state = p.class_2_sim1
答案1
得分: 2
你可以简单地使用枚举值定义全局变量:
from enum import Enum
class enum_class1(Enum):
class1_sym1: int = 0
class1_sym2: int = 1
class1_sym3: int = 2
class1_sym1: int = enum_class1.class1_sym1
class1_sym2: int = enum_class1.class1_sym2
class1_sym3: int = enum_class1.class1_sym3
class enum_class2(Enum):
class2_sym1: int = 0
class2_sym2: int = 1
class2_sym3: int = 2
class2_sym1: int = enum_class2.class2_sym1
class2_sym2: int = enum_class2.class2_sym2
class2_sym3: int = enum_class2.class2_sym3
英文:
You can simply define global variables with the enum values:
from enum import Enum
class enum_class1(Enum):
class1_sym1: int = 0
class1_sym2: int = 1
class1_sym3: int = 2
class1_sym1: int = enum_class1.class1_sym1
class1_sym2: int = enum_class1.class1_sym2
class1_sym3: int = enum_class1.class1_sym3
class enum_class2(Enum):
class2_sym1: int = 0
class2_sym2: int = 1
class2_sym3: int = 2
class2_sym1: int = enum_class2.class2_sym1
class2_sym2: int = enum_class2.class2_sym2
class2_sym3: int = enum_class2.class2_sym3
答案2
得分: 1
以下是您要翻译的内容:
在牺牲静态分析的风险的情况下,您可以通过利用Enum.__members__
映射来自动为每个Enum成员定义全局变量(如Barmar的答案中建议的)。给定以下代码:
class enum_class1(Enum):
class1_sym1: int = 0
class1_sym2: int = 1
class1_sym3: int = 2
我们有:
>>> enum_class1.__members__
mappingproxy({'class1_sym1': <enum_class1.class1_sym1: 0>,
'class1_sym2': <enum_class1.class1_sym2: 1>,
'class1_sym3': <enum_class1.class1_sym3: 2>})
可以使用此映射来填充模块的globals:
globals().update(enum_class1.__members__)
因此,以下代码:
class enum_class1(Enum):
class1_sym1: int = 0
class1_sym2: int = 1
class1_sym3: int = 2
globals().update(enum_class1.__members__)
print(repr(class1_sym1))
会按预期工作,并打印:
<enum_class1.class1_sym1: 0>
英文:
At the risk of compromising static analysis, you can automatically define global variables for each Enum member (as suggested in Barmar's answer) by taking advantage of the Enum.__members__
mapping. Given
class enum_class1(Enum):
class1_sym1: int = 0
class1_sym2: int = 1
class1_sym3: int = 2
we have
>>> enum_class1.__members__
mappingproxy({'class1_sym1': <enum_class1.class1_sym1: 0>,
'class1_sym2': <enum_class1.class1_sym2: 1>,
'class1_sym3': <enum_class1.class1_sym3: 2>})
This mapping can be used to populate the module's globals as
globals().update(enum_class1.__members__)
So,
class enum_class1(Enum):
class1_sym1: int = 0
class1_sym2: int = 1
class1_sym3: int = 2
globals().update(enum_class1.__members__)
print(repr(class1_sym1))
works as expected, and will print
<enum_class1.class1_sym1: 0>
答案3
得分: 1
A more dynamic approach that leverages the __getattr__
in a module would be something like this:
from enum import Enum
class enum_class1(Enum):
class1_sym1: int = 0
class1_sym2: int = 1
class1_sym3: int = 2
class enum_class2(Enum):
class2_sym1: int = 0
class2_sym2: int = 1
class2_sym3: int = 2
def __getattr__(target):
target_cls, target_attr = target.rsplit('_', 1)
if (cls := globals().get(f'enum_{target_cls}')) is not None:
return getattr(cls, f'{target_cls}_{target_attr}')
In [1]: import mypackage as p
In [2]: p.class2_sym1
Out[2]: <enum_class2.class2_sym1: 0>
英文:
A more dynamic approach that leverages the __getattr__
in a module would be something like this:
from enum import Enum
class enum_class1(Enum):
class1_sym1: int = 0
class1_sym2: int = 1
class1_sym3: int = 2
class enum_class2(Enum):
class2_sym1: int = 0
class2_sym2: int = 1
class2_sym3: int = 2
def __getattr__(target):
target_cls, target_attr = target.rsplit('_', 1)
if (cls := globals().get(f'enum_{target_cls}')) is not None:
return getattr(cls, f'{target_cls}_{target_attr}')
In [1]: import mypackage as p
In [2]: p.class2_sym1
Out[2]: <enum_class2.class2_sym1: 0>
答案4
得分: 1
如果你的枚举成员都有不同的名称,你可以这样做:
from enum import Enum, global_enum
@global_enum
class enum_class1(Enum):
class1_sym1: int = 0
class1_sym2: int = 1
class1_sym3: int = 2
现在你可以从模块中访问,并且repr
已更新,不再显示类:
>>> import mypackage as p
>>> state = p.class1_sym1
>>> state
mypackage.class1_sym1
当然,如果你不喜欢默认的方式,你可以自己编写__repr__
。
此外,如果你需要满足一个代码检查工具,可以添加:
class1_sym1 = class1_sym2 = class1_sym3 = None
请注意:我只提供了代码的翻译部分,没有添加任何额外的内容。
英文:
If all your enum members have different names, you can do:
from enum import Enum, global_enum
@global_enum
class enum_class1(Enum):
class1_sym1: int = 0
class1_sym2: int = 1
class1_sym3: int = 2
Now you can access from the module, and the repr is updated to not show the class:
>>> import mypackage as p
>>> state = p.class1_sym1
>>> state
mypackage.class1_sym1
You can, of course, write your own __repr__
if you don't like the default.
Also, if you need to appease a linter, add
class1_sym1 = class1_sym2 = class1_sym3 = None
Disclosure: I am the author of the Python stdlib Enum
, the enum34
backport, and the Advanced Enumeration (aenum
) library.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论