Python 3.11+ 如何创建没有参数传递给init的枚举
问题描述
我有以下代码,在3.9和3.10上按预期工作:
from enum import Enum
class Environment(Enum):
DEV = ()
INT = ()
PROD = ()
def __init__(self):
self._value_ = self.name.lower()
def __str__(self):
return self.name
def get_url(self):
if self is Environment.DEV:
return 'http://localhost'
else:
return f'https://{self.value}.my.domain'
这是在REPL中的结果:
>>> Environment.DEV.get_url()
'http://localhost'
>>> Environment.INT.get_url()
'https://int.my.domain'
>>> Environment.PROD.get_url()
'https://prod.my.domain'
我这样做是因为我阅读到,为枚举定义一个 __init__
方法允许在赋值时传递元组,而我想避免冗余/容易出错的显式声明,例如:
DEV = 'DEV'
INT = 'INT'
PROD = 'PROD'
现在,当我在Python 3.11或3.12上运行相同的代码时,对get_url
的每次调用都返回本地主机URL。在REPL中尝试一下,我们得到:
>>> Environment.DEV.get_url()
'http://localhost'
>>> Environment.INT.get_url()
'http://localhost'
>>> Environment.PROD.get_url()
'http://localhost'
我甚至注意到所有的枚举值都等于第一个值:
>>> Environment.DEV
<Environment.DEV: 'dev'>
>>> Environment.INT
<Environment.DEV: 'dev'>
>>> Environment.PROD
<Environment.DEV: 'dev'>
在Python 3.11中,是有什么改变导致在赋值过程中使用空元组被禁止/破坏?在这些版本中,如何获得相同的结果,即声明枚举值而无需显式传递任何参数给 __init__
?
解决方案
您可以使用 auto()
和 _generate_next_value_()
:
from enum import Enum, auto
class Environment(Enum):
def _generate_next_value_(name, start, count, last_values):
return name
DEV = auto()
INT = auto()
PROD = auto()
这将根据名称自动生成值。
请注意,尽管_generate_next_value_
当前被记录为staticmethod(静态方法),但应用staticmethod装饰器是可选的,并且在之前的版本中不起作用 – 之前的版本需要一个裸函数。