Py学习  »  Python

python中的枚举[重复]

Al3x4ndru1 • 2 年前 • 690 次点击  

我主要是一名C#开发人员,但我目前正在用Python进行一个项目。

如何在Python中表示枚举的等价物?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/132129
 
690 次点击  
文章 [ 5 ]  |  最新文章 2 年前
Jake
Reply   •   1 楼
Jake    10 年前

Python3.4对Enum提供了官方支持。你可以找到文档和例子 here on Python 3.4 documentation page .

枚举是使用类语法创建的,这使它们变得简单 读和写。中描述了另一种创建方法 函数API。要定义枚举,请按如下方式子类Enum:

from enum import Enum
class Color(Enum):
     red = 1
     green = 2
     blue = 3
Natim
Reply   •   2 楼
Natim    10 年前

我更喜欢在Python中定义枚举,如下所示:

class Animal:
  class Dog: pass
  class Cat: pass

x = Animal.Dog

它比使用整数更能防止错误,因为你不必担心确保整数是唯一的(例如,如果你说Dog=1和Cat=1,你就完蛋了)。

它比使用字符串更能防止错误,因为你不必担心拼写错误(例如。 x==“catt”无声地失败,但x==动物。Catt是一个运行时异常)。


增编: 您甚至可以通过让Dog和Cat从具有正确元类的symbol类继承来增强此解决方案:

class SymbolClass(type):
    def __repr__(self): return self.__qualname__
    def __str__(self): return self.__name__

class Symbol(metaclass=SymbolClass): pass


class Animal:
    class Dog(Symbol): pass
    class Cat(Symbol): pass

然后,如果您使用这些值来索引字典,请求它的表示将使它们看起来很好:

>>> mydict = {Animal.Dog: 'Wan Wan', Animal.Cat: 'Nyaa'}
>>> mydict
{Animal.Dog: 'Wan Wan', Animal.Cat: 'Nyaa'}
Jah
Reply   •   3 楼
Jah    10 年前

以下是一个实现:

class Enum(set):
    def __getattr__(self, name):
        if name in self:
            return name
        raise AttributeError

下面是它的用法:

Animals = Enum(["DOG", "CAT", "HORSE"])

print(Animals.DOG)
David
Reply   •   4 楼
David    10 年前

在PEP 435之前,Python没有类似的版本,但您可以实现自己的版本。

我自己,我喜欢保持简单(我在网上看到过一些非常复杂的例子),像这样的。。。

class Animal:
    DOG = 1
    CAT = 2

x = Animal.DOG

在Python 3.4中( PEP 435 ),你可以 Enum name 还有 value .

from enum import Enum

class Animal(Enum):
    DOG = 1
    CAT = 2

print(Animal.DOG)
# <Animal.DOG: 1>

print(Animal.DOG.value)
# 1

print(Animal.DOG.name)
# "DOG"

如果不想键入值,请使用以下快捷方式:

class Animal(Enum):
    DOG, CAT = range(2)

Enum 实现 can be converted to lists and are iterable .其成员的顺序是声明顺序,与他们的价值观无关。例如:

class Animal(Enum):
    DOG = 1
    CAT = 2
    COW = 0

list(Animal)
# [<Animal.DOG: 1>, <Animal.CAT: 2>, <Animal.COW: 0>]

[animal.value for animal in Animal]
# [1, 2, 0]

Animal.CAT in Animal
# True
Rafay
Reply   •   5 楼
Rafay    10 年前

Enums 已添加到Python 3.4中,如中所述 PEP 435 .这也是 backported to 3.3, 3.2, 3.1, 2.7, 2.6, 2.5, and 2.4 在pypi上。

有关更高级的枚举技术,请尝试 aenum library enum34 .代码在py2和py3之间不完全兼容,例如,您需要 __order__ in python 2 ).

  • 使用 $ pip install enum34
  • 使用 aenum $ pip install aenum

安装 enum (无编号)将安装完全不同且不兼容的版本。


from enum import Enum     # for enum34, or the stdlib version
# from aenum import Enum  # for the aenum version
Animal = Enum('Animal', 'ant bee cat dog')

Animal.ant  # returns <Animal.ant: 1>
Animal['ant']  # returns <Animal.ant: 1> (string lookup)
Animal.ant.name  # returns 'ant' (inverse lookup)

或者相当于:

class Animal(Enum):
    ant = 1
    bee = 2
    cat = 3
    dog = 4

在早期版本中,实现枚举的一种方法是:

def enum(**enums):
    return type('Enum', (), enums)

它的用法如下:

>>> Numbers = enum(ONE=1, TWO=2, THREE='three')
>>> Numbers.ONE
1
>>> Numbers.TWO
2
>>> Numbers.THREE
'three'

您还可以通过以下方式轻松支持自动枚举:

def enum(*sequential, **named):
    enums = dict(zip(sequential, range(len(sequential))), **named)
    return type('Enum', (), enums)

这样使用:

>>> Numbers = enum('ZERO', 'ONE', 'TWO')
>>> Numbers.ZERO
0
>>> Numbers.ONE
1

可以通过以下方式添加对将值转换回名称的支持:

def enum(*sequential, **named):
    enums = dict(zip(sequential, range(len(sequential))), **named)
    reverse = dict((value, key) for key, value in enums.iteritems())
    enums['reverse_mapping'] = reverse
    return type('Enum', (), enums)

这将覆盖具有该名称的任何内容,但对于在输出中呈现枚举非常有用。它会抛出一个 KeyError

>>> Numbers.reverse_mapping['three']
'THREE'

如果您使用MyPy,另一种表达“enums”的方法是使用 typing.Literal .

例如:

from typing import Literal #python >=3.8
from typing_extensions import Literal #python 2.7, 3.4-3.7


Animal = Literal['ant', 'bee', 'cat', 'dog']

def hello_animal(animal: Animal):
    print(f"hello {animal}")

hello_animal('rock') # error
hello_animal('bee') # passes