Python: Enum枚举的实现

http://www.cnblogs.com/codingmylife/archive/2013/05/31/3110656.html

   从C系语言过来用Python,好不容易适应了写代码不打花括号,突然有一天发现它居然木有枚举……于是stackoverflow了一把,发现神人的枚举(enum)实现到处都是,于是汉化总结过来。

如果是新版Python用户(Python 3.4 with PEP 435):

1 2

from enum import Enum Animal = Enum('Animal', 'ant bee cat dog')

or

1 2 3 4 5

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

旧版Python用户可以充分发挥动态语言的优越性来构造枚举,有简单的:

1 2 3 4 5

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'

有复杂的:

1 2 3 4 5 6

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

有带值到名称映射的:

1 2 3 4 5 6 7

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实现的:

1 2 3 4 5 6 7 8

class Enum(set):     def __getattr__(self, name):         if name in self:             return name         raise AttributeError   Animals = Enum(["DOG", "CAT", "HORSE"]) print Animals.DOG

有用range实现的:

1 2 3 4 5 6 7

dog, cat, rabbit = range(3)   # or   class Stationary:     (Pen, Pencil, Eraser) = range(0, 3) print Stationary.Pen

有用tuple实现的:

1 2 3 4

class Enum(tuple): __getattr__ = tuple.index   State = Enum(['Unclaimed', 'Claimed']) print State.Claimed

有用namedtuple实现的:

1 2 3 4 5 6 7 8 9 10 11 12 13 14

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())

分类: Python

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏函数式编程语言及工具

PICE(5):MongoDBStreaming - gRPC -MGO Service

  我在前面提到过MongoDB不支持像SQL般字符式的操作指令,所以我们必须对所有的MongoDB操作指令建立protobuf类型才能支持MongoDB指令的...

16240
来自专栏草根专栏

用C# (.NET Core) 实现迭代器设计模式

本文的概念来自深入浅出设计模式一书 项目需求 有两个饭店合并了, 它们各自有自己的菜单. 饭店合并之后要保留这两份菜单. 这两个菜单是这样的: ? 菜单项Men...

37950
来自专栏小古哥的博客园

JavaScript对象创建的九种方式

1、标准创建对象模式 1 var person = new Object(); 2 person.name = "Nicholas"; 3 person.age...

30970
来自专栏菩提树下的杨过

javascript实现数字转大写金额的函数

<SCRIPT type="text/javascript" Charset="GB2312"> function convertCurrency(curre...

25690
来自专栏老马说编程

(51) 剖析EnumSet / 计算机程序的思维逻辑

查看历史文章,请点击上方链接关注公众号。 上节介绍了EnumMap,本节介绍同样针对枚举类型的Set接口的实现类EnumSet。与EnumMap类似,之所以会有...

21970
来自专栏cnblogs

Javascript的原型继承,说清楚

     一直以来对Javascript的原型、原型链、继承等东西都只是会用和了解,但没有深入去理解这门语言关于继承这方面的本质和特点。闲暇之余做的理解和总...

18890
来自专栏悦思悦读

Spark Tips 1: RDD的collect action 不适用于单个element size过大的情况

collect是Spark RDD一个非常易用的action,通过collect可以轻易获得一个RDD当中所有的elements。当这些elements是Str...

36990
来自专栏xdecode

利用Cglib实现AOP

前文讲了, 可以利用Spring, Guice等框架提供的容器实现AOP, 如果想绕过容器, 直接注入Class, 可以利用Cglib为对象加上动态代理,实现代...

28770
来自专栏Flutter入门到实战

老司机带你重构Android的v4包的部分源码

版权声明:本文为博主原创文章,未经博主允许不得转载。https://www.jianshu.com/p/a08d754944c4

20610
来自专栏一个小程序员的成长笔记

理想的继承范式——寄生组合式继承

9130

扫码关注云+社区

领取腾讯云代金券