如何使用其他方法从现有字典创建Python枚举类?

瓦齐尔

假设我有一个预先存在的映射作为字典:

value_map = {'a': 1, 'b': 2}

我可以这样创建一个枚举类:

from enum import Enum
MyEnum = Enum('MyEnum', value_map)

像这样使用

a = MyEnum.a
print(a.value)
>>> 1
print(a.name)
>>> 'a'

但是然后我想为我的新枚举类定义一些方法:

def double_value(self):
    return self.value * 2

当然,我可以这样做:

class MyEnum(Enum):
    a = 1
    b = 2
    @property
    def double_value(self):
        return self.value * 2

但是正如我所说,我必须使用预定义的值映射字典,所以我不能这样做。如何做到这一点?我试图从另一个类(定义为mixin)继承该方法,但我无法弄清楚。

马丁·彼得斯(Martijn Pieters)

您可以将带有mixin方法的基本类型与type参数一起传递给功能性API

>>> import enum
>>> value_map = {'a': 1, 'b': 2}
>>> class DoubledEnum:
...     @property
...     def double_value(self):
...         return self.value * 2
...
>>> MyEnum = enum.Enum('MyEnum', value_map, type=DoubledEnum)
>>> MyEnum.a.double_value
2

对于一个全功能的做法,从来没有使用class的语句,你可以创建基MIX-与type()功能

DoubledEnum = type('DoubledEnum', (), {'double_value': property(double_value)})
MyEnum = enum.Enum('MyEnum', value_map, type=DoubledEnum)

您还可以使用enum.EnumMeta()与创建class MyEnum(enum.Enum): ...子类时Python相同的方式使用类:

  1. 使用元类钩子创建类字典__prepare__
  2. 调用元类,并传入(enum.Enum,)步骤1中创建的类名称,基数(此处)和类字典。

使用的自定义字典子类enum.EnumMeta并不是为易于重用而设计的。它实现了一个__setitem__记录元数据钩子,但没有覆盖该dict.update()方法,因此在使用value_map字典时我们需要格外小心

import enum

def enum_with_extras(name, value_map, bases=enum.Enum, **extras):
    if not isinstance(bases, tuple):
        bases = bases,
    if not any(issubclass(b, enum.Enum) for b in bases):
        bases += enum.Enum,
    classdict = enum.EnumMeta.__prepare__(name, bases)
    for key, value in {**value_map, **extras}.items():
        classdict[key] = value
    return enum.EnumMeta(name, bases, classdict)

然后传入double_value=property(double_value)该函数(连同枚举名称和value_map字典):

>>> def double_value(self):
...     return self.value * 2
...
>>> MyEnum = enum_with_extras('MyEnum', value_map, double_value=property(double_value))
>>> MyEnum.a
<MyEnum.a: 1>
>>> MyEnum.a.double_value
2

否则,您可以创建不带成员的枚举的子类(任何不是描述符的成员,因此函数,属性,类方法等),因此可以先定义不带成员的枚举:

class DoubledEnum(enum.Enum):
    @property
    def double_value(self):
        return self.value * 2

对于功能性API(例如enum.Enum(..., type=DoubledEnum))和我编码为的元类方法,这都是可接受的基类enum_with_extras()

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Python 类调用其他方法

有使用其他类方法的其他方法吗?

如何在枚举中调用其他方法?

如何使用其他方法的输入?

如何使用作业 DSL 或其他方式启用 Jenkins 中的现有作业?

如何在调用其他方法的基类上创建Java方法?

Java:使用在其他方法和类的main方法中创建的数组

如何在没有其他枚举的情况下创建可枚举类?

您如何使方法内部产生的变量可用于类中的所有其他方法?

如何通过使用python中的现有列创建以其他列为条件的新列

如何为其他方法封装类方法

如何从类的其他方法访问该方法?

在测试类的其他方法使用对象

是否有其他方法可以创建空数组,然后将其填充到Python中?

在以其他方法创建的对象上使用

类方法指向其他类的其他方法

如何使用numpy广播,meshgrid或其他方法创建字符矩阵

如何使用锁或其他方法暂停由asyncio创建的任务?

如何存储创建的POST请求ID值以在其他方法中使用

如何在javascript中使用map或其他方法创建自定义数组?

如何使用 PHP 中的循环或其他方法从数组创建多维数组

如何创建其他类共有的方法

使用通用类访问其他类中的其他方法

如何防止 Git 在“结帐”时使用“umask”(或以其他方式保留现有文件和目录权限)?

如何在onCreat()中具有变量的值以在其他方法中使用

如何使用字典或其他方法将df1传输到df2

如何使用yum或其他方法删除docker

如何在Python中删除慢循环并使用Lambda或其他方法

JavaScript类-使用WeakMap将变量设为私有,并在其他方法中仍使用“ this”