Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
向Python枚举添加成员_Python_Dynamic_Enums - Fatal编程技术网

向Python枚举添加成员

向Python枚举添加成员,python,dynamic,enums,Python,Dynamic,Enums,我知道这不是标准用例,但我需要在Python中向IntEnum派生类动态添加元素。请注意,使用函数API动态创建枚举是不够的。我需要向现有枚举添加元素。我该怎么做 背景:对于那些想知道为什么会有人想这样做的人来说。我正在包装一个库,枚举的值在库中定义。我可以使用库API查询名称和值。但我无法在初始化时执行此操作,因为它依赖于库根据用户请求动态加载的组件。我可以在启动时加载所有组件,并在导入时使用函数API创建枚举,但这很耗时,而且有副作用。枚举是不可变的,这才是重点。您可以创建一个新的枚举来替换

我知道这不是标准用例,但我需要在Python中向
IntEnum
派生类动态添加元素。请注意,使用函数API动态创建枚举是不够的。我需要向现有枚举添加元素。我该怎么做

背景:对于那些想知道为什么会有人想这样做的人来说。我正在包装一个库,枚举的值在库中定义。我可以使用库API查询名称和值。但我无法在初始化时执行此操作,因为它依赖于库根据用户请求动态加载的组件。我可以在启动时加载所有组件,并在导入时使用函数API创建枚举,但这很耗时,而且有副作用。

枚举是不可变的,这才是重点。您可以创建一个新的枚举来替换原始枚举:

from enum import Enum

names = [m.name for m in ExistingEnum] + ['newname1', 'newname2']
ExistingEnum = Enum('ExistingEnum', names)
但是任何现有的引用(比如在其他模块中)都将继续使用旧的定义

名称可以是:

  • 包含成员名称的字符串,用空格或逗号分隔。值从
    start
    开始递增1(可设置为关键字参数,默认为1)
  • 成员名称的一个iterable(如上面的代码所示)。值从
    开始
    递增1
  • (成员名称、值)对的可数
  • 成员名称->值对的映射

这是1的
extend_enum
函数的作业


一对样本
Enum
s:

from aenum import Enum

class Color(Enum):
    black = 0

class ColorHelp(Enum):
    _init_ = 'value __doc__'
    black = 0, 'the absence of color'
extend_enum
正在运行:

from aenum import extend_enum

extend_enum(Color, 'white', 1)
print Color, list(Color)
print repr(Color.black), Color.black, repr(Color.white), Color.white
print

extend_enum(ColorHelp, 'white', 1, 'the presence of every color')
print ColorHelp, list(ColorHelp)
print repr(ColorHelp.black), ColorHelp.black, ColorHelp.black.__doc__, repr(ColorHelp.white), ColorHelp.white, ColorHelp.white.__doc__
这给了我们:

<enum 'Color'> [<Color.black: 0>, <Color.white: 1>]
<Color.black: 0> Color.black <Color.white: 1> Color.white

<enum 'ColorHelp'> [<ColorHelp.black: 0>, <ColorHelp.white: 1>]
<ColorHelp.black: 0> ColorHelp.black the absence of color <ColorHelp.white: (1, 'the presence of every color')> ColorHelp.white None
[,]
颜色。黑色。白色
[, ]
ColorHelp.black缺少颜色ColorHelp.white无


1披露:我是、和库的作者。

ENUM的全部要点不是不变性吗?你不能。即使是扩展现有枚举的子类也会受到保护。@MartijnPorters对这个特定用例有什么建议吗?@MightyPort是的,但是Python是一种很棒的动态粘合语言,很多时候你需要与你无法控制的东西进行交互。@Hernan:我很好奇你为什么不接受满足你需要的答案?正如我所提到的,这不是一种选择,原因与你描述的完全相同。谢谢anyway@Hernan:但是,这是使用
enum
库时的唯一选项。不可变性不是枚举的“要点”。枚举的存在是为了保证有限无序集上的互斥性。在运行时将其他成员追加到现有枚举中不会违反此保证。Python的标准
enum.enum
类型选择禁止此有效用例,但决不禁止第三方替代方案这样做。另请参见:可变和类型。@CecilCurry:这两个库都没有改变原始枚举,而是在现有枚举上扩展以创建新枚举。如果枚举在运行时是可变的,这将产生广泛的影响,您无法再保证处理所有可能的值(像Rust这样的语言甚至在不可在运行时可变的枚举上构建其类型安全性),第2166行,在canonical_成员中的canonical_值的扩展_枚举中。\u值:AttributeError:'MachineName'对象没有属性'values',其中MachineName是常用的python枚举。这个方法还有效吗?@likern,如果这仍然是一个问题,请。谢谢。对于任何与@likern有相同错误的人,请确保使用aenum的枚举(
来自aenum导入枚举
),而不是常规枚举(
来自Enum导入枚举
)。它也是可酸洗的。@Ethafurman我想更正我之前的评论。我无法加载带有扩展枚举的pickle对象。默认枚举定义不包括某些项。ValueError:不是有效的