Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.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_Python 3.x_String_Enums - Fatal编程技术网

Python中基于字符串的枚举

Python中基于字符串的枚举,python,python-3.x,string,enums,Python,Python 3.x,String,Enums,要封装我正在使用的enum模块的状态列表: from enum import Enum class MyEnum(Enum): state1='state1' state2 = 'state2' state = MyEnum.state1 MyEnum['state1'] == state # here it works 'state1' == state # here it does not throw but returns False (fail!) 但是,问题是

要封装我正在使用的
enum
模块的状态列表:

from enum import Enum

class MyEnum(Enum):
    state1='state1'
    state2 = 'state2'

state = MyEnum.state1
MyEnum['state1'] == state  # here it works
'state1' == state  # here it does not throw but returns False (fail!)
但是,问题是我需要在脚本中的许多上下文中将值无缝地用作字符串,例如:

select_query1 = select(...).where(Process.status == str(MyEnum.state1))  # works but ugly

select_query2 = select(...).where(Process.status == MyEnum.state1)  # throws exeption

如何避免调用额外的类型转换(
str(state)
以上)或底层值(
state.value
)?

似乎在
Enum
的同时从
str
类继承就足够了:

class MyEnum(str, Enum):
    state1='state1'
    state2 = 'state2'
棘手的部分是继承链中类的顺序很重要,如下所示:

抛出:

TypeError: new enumerations should be created as `EnumName([mixin_type, ...] [data_type,] enum_type)`
使用正确的类,MyEnum上的以下操作可以正常进行:

print('This is the state value: ' + state)

作为旁注,似乎不需要特殊的继承技巧,即使只适用于
Enum
继承:

msg = f'This is the state value: {state}'  # works without inheriting from str

虽然
str
Enum
之间的mixin类可以解决这个问题,但您也应该始终考虑为作业找到合适的工具

有时,正确的工具可能只是一个带有字符串值的MODULE_常量。例如,
logging
有一些常量,如DEBUG、INFO等,这些常量具有有意义的值,即使在本例中它们是
int
s


枚举是一个很好的工具,我经常使用它们。但是,它们主要用于与同一枚举的其他成员进行比较,这就是为什么将它们与字符串(例如字符串)进行比较需要您跳转到另一个环。

尝试更改数据库中状态的数据类型以匹配枚举。某些数据库不允许,或者也尝试使用临时表副本。

如果关联的字符串值是有效的Python名称,则可以使用
.name
属性获取枚举成员的名称,如下所示:

from enum import Enum
class MyEnum(Enum):
    state1=0
    state2=1

print (MyEnum.state1.name)  # 'state1'

a = MyEnum.state1
print(a.name)  # 'state1'

如果关联的字符串值是任意字符串,则可以执行以下操作:

class ModelNames(str, Enum):
    gpt2 = 'gpt2'
    distilgpt2 = 'distilgpt2'
    gpt2_xl = 'gpt2-XL'
    gpt2_large = 'gpt2-large'

print(ModelNames.gpt2) # 'ModelNames.gpt2'
print(ModelNames.gpt2 is str) # False
print(ModelNames.gpt2_xl.name) # 'gpt2_xl'
print(ModelNames.gpt2_xl.value) # 'gpt2-XL'
联机尝试此选项:

只需使用。值:

MyEnum.state1.value == 'state1'
# True

MyEnum.state1.value
?对不起,这和我认为的
str(state)
一样难看……什么类型是
Testround.status
?您可以将其设置为MyEnum类型吗?您的示例代码
'state1'==state
是错误的——该比较返回
False
@EthanFurman:它不会抛出,但结果确实远远不能令人满意。谢谢更正。相关文档:请注意,a
str
mixin可能会产生意外的副作用,例如(反)序列化行为;例如,请参阅创建的
Enum
,这样就不需要不透明的模块常量。@EthanFurman那么为什么logging.DEBUG和friends没有被弃用?它们不会被弃用--它们将被相应的
IntEnum
替换。标准策略是尽可能保持stdlib的稳定性,这意味着不必为了利用每一个新特性而大量重写它。到目前为止,
http
socket
re
模块常量已经被替换(可能还有一些我现在不记得了)。的相关部分。哇,感觉我们已经很久没谈过了!这里的要点与我之前的评论有关:没有充分的理由不要重写stdlib。魔术字符串的情况更难解释,因为这些字符串通常是不言自明的。最有可能进行
Enum
转换的模块是面向用户的整数常量(例如
re
http
)。另外,不转换stdlib的特定部分的一个重要原因是它是否在可以导入
Enum
之前使用。这些都是不影响stdlib之外的代码的原因,我们这里不是在谈论数据库。这都是关于Python代码的。问题明确指出,调用
.value
不是一个可接受的解决方案。
MyEnum.state1.value == 'state1'
# True