Python 3.11+ 如何创建没有参数传递给__init__的枚举

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装饰器是可选的,并且在之前的版本中不起作用 – 之前的版本需要一个裸函数。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程