從C系語言過來用Python,好不容易適應了寫代碼不打花括號,突然有一天發現它居然木有枚舉……於是stackoverflow了一把,發現神人的枚舉(enum)實現到處都是,於是漢化總結過來。
如果是新版Python用戶(Python 3.4 with PEP 435):
from enum import Enum
Animal = Enum('Animal', 'ant bee cat dog')
or
class Animals(Enum):
ant = 1
bee = 2
cat = 3
dog = 4
舊版Python用戶可以充分發揮動態語言的優越性來構造枚舉,有簡單的:
def enum(**enums):
return type('Enum', (), enums)
Numbers = enum(ONE=1, TWO=2, THREE='three')
# Numbers.ONE == 1, Numbers.TWO == 2 and 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 and 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)
# Numbers.reverse_mapping['three'] == 'THREE'
有用set實現的:
class Enum(set):
def __getattr__(self, name):
if name in self:
return name
raise AttributeError
Animals = Enum(["DOG", "CAT", "HORSE"])
print Animals.DOG
有用range實現的:
dog, cat, rabbit = range(3)
# or
class Stationary:
(Pen, Pencil, Eraser) = range(0, 3)
print Stationary.Pen
有用tuple實現的:
class Enum(tuple): __getattr__ = tuple.index State = Enum(['Unclaimed', 'Claimed']) print State.Claimed
有用namedtuple實現的:
from collections import namedtuple
def enum(*keys):
return namedtuple('Enum', keys)(*keys)
MyEnum = enum('FOO', 'BAR', 'BAZ')
# 帶字符數字映射的,像C/C++
def enum(*keys):
return namedtuple('Enum', keys)(*range(len(keys)))
# 帶字典映射的,可以映射出各種類型,不局限於數字
def enum(**kwargs):
return namedtuple('Enum', kwargs.keys())(*kwargs.values())
