1. 枚举的定义

首先,定义枚举要导入enum模块。
枚举定义用class关键字,继承Enum类。
用于定义枚举的class和定义类的class是有区别。

示例代码:

from enum import Enum

class Color(Enum):
    red = 1
    orange = 2
    yellow = 3
    green = 4
    blue = 5
    indigo = 6
    purple = 7

代码分析:

  1. 上面的代码,我们定义了颜色的枚举Color.
  2. 颜色枚举有7个成员,分别是Color.red、Color.orange、Color.yellow等。
  3. 每一个成员都有它们各自名称和值,Color.red成员的名称是:red,值是:1。
  4. 每个成员的数据类型就是它所属的枚举。【*注:用class定义的类,实际上就是一种类型】

1.1 定义枚举时,成员名称不允许重复

from enum import Enum

class Color(Enum):
    red = 1
    red = 2

上面的代码,就无法执行。提示错误:TypeError: Attempted to reuse key: 'red'

1.2 默认情况下,不同的成员值允许相同。但是两个相同值的成员,第二个成员的名称被视作第一个成员的别名

from enum import Enum

class Color(Enum):
    red = 1
    red_alias = 1

成员Color.red和Color.red_alias具有相同的值,那么成员Color.red_alias的名称red_alias就被视作成员Color.red名称red的别名。

1.3 如果枚举中存在相同值的成员,在通过值获取枚举成员时,只能获取到第一个成员

from enum import Enum

class Color(Enum):
    red = 1
    red_alias = 1

print(Color(1))

输出结果为:Color.red

1.4 如果要限制定义枚举时,不能定义相同值的成员。可以使用装饰器@unique【要导入unique模块】

from enum import Enum, unique

@unique
class Color(Enum):
    red = 1
    red_alias = 1

再执行就会提示错误:ValueError: duplicate values found in <enum 'Color'>: red_alias -> red

2. 枚举取值

2.1 通过成员的名称来获取成员

Color['red']

2.2 通过成员值来获取成员

Color(2)

2.3 通过成员,来获取它的名称和值

red_member = Color.red
red_member.name
red_member.value

3. 迭代器

3.1 枚举支持迭代器,可以遍历枚举成员

for color in Color:
    print(color)

输出结果是,枚举的所有成员。Color.red、Color.orange、Color.yellow、Color.green、Color.blue、Color.indigo、Color.purple。

3.2 如果枚举有值重复的成员,循环遍历枚举时只获取值重复成员的第一个成员

from enum import Enum

class Color(Enum):
    red = 1
    orange = 2
    yellow = 3
    green = 4
    blue = 5
    indigo = 6
    purple = 7
    red_alias = 1

for color in Color:
    print(color)

输出结果是:Color.red、Color.orange、Color.yellow、Color.green、Color.blue、Color.indigo、Color.purple。但是Color.red_alias并没有出现在输出结果中。

3.3 如果想把值重复的成员也遍历出来,要用枚举的一个特殊属性_members_

from enum import Enum

class Color(Enum):
    red = 1
    orange = 2
    yellow = 3
    green = 4
    blue = 5
    indigo = 6
    purple = 7
    red_alias = 1

for color in Color.__members__.items():
    print(color)

输出结果:('red', <Color.red: 1>)、('orange', <Color.orange: 2>)、('yellow', <Color.yellow: 3>)、('green', <Color.green: 4>)、('blue', <Color.blue: 5>)、('indigo', <Color.indigo: 6>)、('purple', <Color.purple: 7>)、('red_alias', <Color.red: 1>)

4. 枚举比较

4.1 枚举成员可进行同一性比较

Color.red is Color.red

输出结果是:True

Color.red is not Color.blue

输出结果是:True

4.2 枚举成员可进等值比较

Color.blue == Color.red

输出结果是:False

Color.blue != Color.red

输出结果是:True

4.3 枚举成员不能进行大小比较

Color.red < Color.blue

输出结果出错:TypeError: unorderable types: Color() < Color()


# 枚举类 Enum
from enum import Enum

Month = Enum('Month',('Jan','Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))

for name,member in Month.__members__.items():
    # value属性则是自动赋给成员的int常量,默认从1开始计数
    print(name,'=>',member,',',member.value) 

# 输出结果
# Jan => Month.Jan , 1
# Feb => Month.Feb , 2
# Mar => Month.Mar , 3
# Apr => Month.Apr , 4
# May => Month.May , 5
# Jun => Month.Jun , 6
# Jul => Month.Jul , 7
# Aug => Month.Aug , 8
# Sep => Month.Sep , 9
# Oct => Month.Oct , 10
# Nov => Month.Nov , 11
# Dec => Month.Dec , 12

# 如果需要更精确地控制枚举类型,可以从Enum派生出自定义类
from enum import Enum,unique

@unique
class WeekDay(Enum):
    Sun = 0 #设置sun 的value为0
    Mon = 1
    Tue = 2
    Wed = 3
    Thu = 4
    Fri = 5
    Sat = 6
    # Sat = 6 # 如果重复会报错 TypeError: Attempted to reuse key: 'Sat'
    # @unique装饰器可以帮助我们检查保证没有重复值

# 访问这些枚举类型可以有若干种方法:
day1 = WeekDay.Mon
print(day1) # WeekDay.Mon

print(WeekDay.Thu) # WeekDay.Thu

print(WeekDay['Tue']) # WeekDay.Tue

print(day1 == WeekDay.Mon) # True

print(day1 == WeekDay.Sun) # False

print(WeekDay(1)) # WeekDay.Mon

print(day1 == WeekDay(1)) # True

print(Weekday(7)) # NameError: name 'Weekday' is not defined

python type()动态创建类

type()函数可以查看一个类型或变量的类型,Hello是一个class,它的类型就是type,而h是一个实例,它的类型就是class Hello。

我们说class的定义是运行时动态创建的,而创建class的方法就是使用type()函数。

type()函数既可以返回一个对象的类型,又可以创建出新的类型,比如,我们可以通过type()函数创建出Hello类,而无需通过class Hello(object)…的定义:

def fn(self,name='world'):
    print('hello,%s.' % name)
Hello = type('Hello',(object,),dict(hello=fn))
h = Hello()

h.hello() # hello world.

h.hello('py') # hello py.

print(type(Hello)) # <class 'type'>

print(type(h)) # <class '__main__.Hello'>

要创建一个class对象,type()函数依次传入3个参数:

class的名称;
继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;
class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上。
通过type()函数创建的类和直接写class是完全一样的,因为Python解释器遇到class定义时,仅仅是扫描一下class定义的语法,然后调用type()函数创建出class。

正常情况下,我们都用class Xxx…来定义类,但是,type()函数也允许我们动态创建出类来,也就是说,动态语言本身支持运行期动态创建类,这和静态语言有非常大的不同,要在静态语言运行期创建类,必须构造源代码字符串再调用编译器,或者借助一些工具生成字节码实现,本质上都是动态编译,会非常复杂。

Python 枚举的更多相关文章

  1. Python 枚举 enum

    Python 枚举 enum enum 标准模块在 3.4 版本才可以使用,3.3 以下版本需要独立安装:https://pypi.python.org/pypi/enum34#downloads,官 ...

  2. python 枚举Enum

    常量是任何一门语言中都会使用的一种变量类型 如 要表示星期常量,我们可能会直接定义一组变量 JAN = 1 TWO = 2 ... 然后在返回给前端的时候,我们返回的就会是1,2,...这种魔法数字, ...

  3. 人生苦短之Python枚举类型enum

    枚举类型enum是比较重要的一个数据类型,它是一种数据类型而不是数据结构,我们通常将一组常用的常数声明成枚举类型方便后续的使用.当一个变量有几种可能的取值的时候,我们将它定义为枚举类型.在Python ...

  4. 谁是嫌疑犯问题Python枚举法

    原文:https://blog.csdn.net/yunzifengqing/article/details/81941592 问题描述:有6名犯罪嫌疑人A.B.C.D.E.F,已知如下事实: A.B ...

  5. python 枚举类型

    在python中枚举是一种类(Enum,IntEnum),存放在enum模块中.枚举类型可以给一组标签赋予一组特定的值. 枚举的特点: 枚举类中不能存在相同的标签名 枚举是可迭代的 不同的枚举标签可以 ...

  6. python枚举类型 Enum

    在python中枚举是一种类(Enum) 枚举类中不能存在相同的标签名 枚举是可迭代的 例: from enum import Enum class Vip(Enum): MONDAY = 0 TUE ...

  7. python枚举类型

    笔记: 一:枚举类型的定义二:枚举类和普通类的区别 1:值不可变 2:具有防止相同标签得功能,不同标签的值可以相同! 三:枚举类型.枚举值.枚举名称 1:VIP.YELLOW.Value 获得标签的值 ...

  8. Python枚举类

    Enum可以把一组相关常量定义在一个class中,且class不可变,而且成员可以直接比较. 定义枚举类: from enum import Enum, unique @unique class We ...

  9. Python 枚举【一】

    1. 枚举的定义 首先,定义枚举要导入enum模块. 枚举定义用class关键字,继承Enum类. 用于定义枚举的class和定义类的class是有区别[下一篇博文继续分享]. 示例代码: from ...

随机推荐

  1. PLSQL表

    PL/SQL表 一,什么是PL/SQL表? 首先PL/SQL表和记录(Record)一样,都是复合数据类型.可以看做是一种用户自定义数据类型. PL/SQL表由多列单行的标量构成的临时索引表对象.组成 ...

  2. ios中XMPP的搭建

    1 首先下载xmppframework这个框架 https://github.com/robbiehanson/XMPPFramework   2 环境配置 参考:https://github.com ...

  3. 如何将windows格式的图标作为os x应用程序的图标

    刚由windows转为os x的同学可能知道,在os x下我们想改变一个app的图标异常简单,直接打开该app的简介,然后将图标文件拖入简介窗口左上角图标方框即可.但是很多童鞋下载了一些图标文件后发现 ...

  4. Spring对事务管理的支持的发展历程(基础篇)

    1.问题 Connection conn = DataSourceUtils.getConnection(); //开启事务 conn.setAutoCommit(false); try { Obje ...

  5. PLSQL学习教程(全)

    基于ORACLE9i+PL/SQLDeveloper7.1.4) 课程 一 PL/SQL 基本查询与排序 本课重点: 1.写SELECT语句进行数据库查询 2.进行数学运算 3.处理空值 4.使用别名 ...

  6. 使用nginx sticky实现基于cookie的负载均衡

    在多台后台服务器的环境下,我们为了确保一个客户只和一台服务器通信,我们势必使用长连接.使用什么方式来实现这种连接呢,常见的有使用nginx自带的ip_hash来做,我想这绝对不是一个好的办法,如果前端 ...

  7. JSP指令与动作

    Jsp基本指令和动作 (2011-08-18 16:25:13) 转载▼ 标签: 杂谈 分类: java JSP基本指令 jsp命令指令用来设置与整个jsp页面相关的属性,它并不直接产生任何可见的输出 ...

  8. Python import this : The Zen of Python

    >>> import thisThe Zen of Python, by Tim Peters Beautiful is better than ugly.Explicit is b ...

  9. Django1.10 release notes摘编

    一.重点新特性: 1.面向PostgreSQL的全文搜索支持 2.新式风格的middleware 3.用户名Unicode编码的官方支持 二.一些可以提的改变: 1.用户名最大长度增加到150 2.不 ...

  10. ruby1.9.2 +windowxp

    ruby1.9.2 install on the window xp 1:在公司上網是有windows代理的(ntlm),而rails又都是gem安裝,對于接觸rails不多的人來時真是一場災難,我是 ...