Skip to content

Commit 6250213

Browse files
committed
Signed-off-by: twowater <[email protected]>
1 parent 245dd86 commit 6250213

File tree

7 files changed

+207
-2
lines changed

7 files changed

+207
-2
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@
1717
|草根学Python(七) 迭代器和生成器|[掘金](https://juejin.im/post/59589fedf265da6c386ce4ac)[简书](http://www.jianshu.com/p/74c0c1db1490)[CSDN](http://blog.csdn.net/Two_Water/article/details/74164652)[个人博客](http://twowater.com.cn/2017/07/02/%E8%8D%89%E6%A0%B9%E5%AD%A6Python-%E4%B8%83-%E8%BF%AD%E4%BB%A3%E5%99%A8%E5%92%8C%E7%94%9F%E6%88%90%E5%99%A8/)|
1818
|草根学Python(八) 模块与包|[掘金](https://juejin.im/post/5962ddf95188252ec34009da)[简书](http://www.jianshu.com/p/7f05f915d2ac)[CSDN](http://blog.csdn.net/Two_Water/article/details/75042211)[个人博客](http://twowater.com.cn/2017/07/12/%E8%8D%89%E6%A0%B9%E5%AD%A6Python-%E5%85%AB-%E6%A8%A1%E5%9D%97%E4%B8%8E%E5%8C%85/)|
1919
|草根学Python(九) 面向对象|[掘金](https://juejin.im/post/596ca6656fb9a06b9b73c8b0)[简书](http://www.jianshu.com/p/6ecaa414c702)[CSDN](http://blog.csdn.net/two_water/article/details/76408890)[个人博客](http://twowater.com.cn/2017/07/31/%E8%8D%89%E6%A0%B9%E5%AD%A6Python-%E4%B9%9D-%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/)|
20-
|草根学Python(十)Python 的 Magic Method|[掘金](https://juejin.im/post/59828c2f6fb9a03c56319baa)[简书](http://www.jianshu.com/p/345a80a02546)[CSDN](http://blog.csdn.net/two_water/article/details/77351516)[个人博客](http://twowater.com.cn/2017/08/18/%E8%8D%89%E6%A0%B9%E5%AD%A6Python-%E5%8D%81-Python-%E7%9A%84-Magic-Method/)|
20+
|草根学Python(十)Python 的 Magic Method|[掘金](https://juejin.im/post/59828c2f6fb9a03c56319baa)[简书](http://www.jianshu.com/p/345a80a02546)[CSDN](http://blog.csdn.net/two_water/article/details/77351516)[个人博客](http://twowater.com.cn/2017/08/18/%E8%8D%89%E6%A0%B9%E5%AD%A6Python-%E5%8D%81-Python-%E7%9A%84-Magic-Method/)|
21+
|草根学Python(十)Python 的 Magic Method|[掘金](https://juejin.im/post/599906a2f265da24722faec3)[简书](http://www.jianshu.com/p/c4d2629e5015)[CSDN](http://blog.csdn.net/Two_Water/article/details/77626179)[个人博客](http://twowater.com.cn/2017/08/28/%E8%8D%89%E6%A0%B9%E5%AD%A6Python-%E5%8D%81%E4%B8%80-%E6%9E%9A%E4%B8%BE%E7%B1%BB/)|

SUMMARY.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,9 @@
5656
- [属性的访问控制](/python10/3.md)
5757
- [对象的描述器](/python10/4.md)
5858
- [自定义容器(Container)](/python10/5.md)
59-
- [运算符相关的魔术方法](/python10/6.md)
59+
- [运算符相关的魔术方法](/python10/6.md)
60+
* [草根学Python(十一)枚举类](/python11/Preface.md)
61+
- [枚举类的使用](/python11/1.md)
62+
- [Enum 的源码](/python11/2.md)
63+
- [自定义类型的枚举](/python11/3.md)
64+
- [枚举的比较](/python11/4.md)

python11/1.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# 一、枚举类的使用 #
2+
3+
实际开发中,我们离不开定义常量,当我们需要定义常量时,其中一个办法是用大写变量通过整数来定义,例如月份:
4+
5+
```python
6+
JAN = 1
7+
FEB = 2
8+
MAR = 3
9+
...
10+
NOV = 11
11+
DEC = 12
12+
```
13+
14+
当然这样做简单快捷,缺点是类型是 `int` ,并且仍然是变量。
15+
16+
那有没有什么好的方法呢?
17+
18+
这时候我们定义一个 class 类型,每个常量都是 class 里面唯一的实例。正好 Python 提供了 Enum 类来实现这个功能如下:
19+
20+
```python
21+
#!/usr/bin/env python3
22+
# -*- coding: UTF-8 -*-
23+
24+
from enum import Enum
25+
26+
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
27+
28+
# 遍历枚举类型
29+
for name, member in Month.__members__.items():
30+
print(name, '---------', member, '----------', member.value)
31+
32+
# 直接引用一个常量
33+
print('\n', Month.Jan)
34+
35+
```
36+
37+
输出的结果如下:
38+
39+
40+
![Python3 枚举类型的使用](https://user-gold-cdn.xitu.io/2017/8/20/68bc0c10a2f7026fdcb4b0e7230d5db6)
41+
42+
可见,我们可以直接使用 `Enum` 来定义一个枚举类。上面的代码,我们创建了一个有关月份的枚举类型 Month ,这里要注意的是构造参数,第一个参数 Month 表示的是该枚举类的类名,第二个 tuple 参数,表示的是枚举类的值;当然,枚举类通过 `__members__` 遍历它的所有成员的方法。注意的一点是 , `member.value` 是自动赋给成员的 `int`类型的常量,默认是从 1 开始的。而且 Enum 的成员均为单例(Singleton),并且不可实例化,不可更改

python11/2.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# 二、Enum 的源码 #
2+
3+
通过上面的实例可以知道通过 `__members__` 可以遍历枚举类的所有成员。那为什么呢?
4+
5+
我们可以先来大致看看 Enum 的源码是如何实现的;Enum 在模块 enum.py 中,先来看看 Enum 类的片段
6+
7+
```python
8+
class Enum(metaclass=EnumMeta):
9+
"""Generic enumeration.
10+
Derive from this class to define new enumerations.
11+
"""
12+
```
13+
14+
可以看到,Enum 是继承元类 EnumMeta 的;再看看 EnumMeta 的相关片段
15+
16+
```python
17+
class EnumMeta(type):
18+
"""Metaclass for Enum"""
19+
@property
20+
def __members__(cls):
21+
"""Returns a mapping of member name->value.
22+
This mapping lists all enum members, including aliases. Note that this
23+
is a read-only view of the internal mapping.
24+
"""
25+
return MappingProxyType(cls._member_map_)
26+
```
27+
28+
首先 `__members__` 方法返回的是一个包含一个 Dict 既 Map 的 MappingProxyType,并且通过 @property 将方法 `__members__(cls)` 的访问方式改变为了变量的的形式,既可以直接通过 `__members__` 来进行访问了

python11/3.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# 三、自定义类型的枚举 #
2+
3+
但有些时候我们需要控制枚举的类型,那么我们可以 Enum 派生出自定义类来满足这种需要。通过修改上面的例子:
4+
5+
```python
6+
#!/usr/bin/env python3
7+
# -*- coding: UTF-8 -*-
8+
from enum import Enum, unique
9+
10+
Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
11+
12+
13+
# @unique 装饰器可以帮助我们检查保证没有重复值
14+
@unique
15+
class Month(Enum):
16+
Jan = 'January'
17+
Feb = 'February'
18+
Mar = 'March'
19+
Apr = 'April'
20+
May = 'May'
21+
Jun = 'June'
22+
Jul = 'July'
23+
Aug = 'August'
24+
Sep = 'September '
25+
Oct = 'October'
26+
Nov = 'November'
27+
Dec = 'December'
28+
29+
30+
if __name__ == '__main__':
31+
print(Month.Jan, '----------',
32+
Month.Jan.name, '----------', Month.Jan.value)
33+
for name, member in Month.__members__.items():
34+
print(name, '----------', member, '----------', member.value)
35+
36+
```
37+
38+
39+
输出的结果如下:
40+
41+
![Python3 自定义类型的枚举类](https://user-gold-cdn.xitu.io/2017/8/20/a59e989e702ccddfa5539b16fdcffa02)
42+
43+
44+
45+
通过上面的例子,可以知道枚举模块定义了具有迭代 (interator) 和比较(comparison) 功能的枚举类型。 它可以用来为值创建明确定义的符号,而不是使用具体的整数或字符串。

python11/4.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# 四、枚举的比较 #
2+
3+
因为枚举成员不是有序的,所以它们只支持通过标识(identity) 和相等性 (equality) 进行比较。下面来看看 `==``is` 的使用:
4+
5+
```python
6+
7+
#!/usr/bin/env python3
8+
# -*- coding: UTF-8 -*-
9+
from enum import Enum
10+
11+
12+
class User(Enum):
13+
Twowater = 98
14+
Liangdianshui = 30
15+
Tom = 12
16+
17+
18+
Twowater = User.Twowater
19+
Liangdianshui = User.Liangdianshui
20+
21+
print(Twowater == Liangdianshui, Twowater == User.Twowater)
22+
print(Twowater is Liangdianshui, Twowater is User.Twowater)
23+
24+
try:
25+
print('\n'.join(' ' + s.name for s in sorted(User)))
26+
except TypeError as err:
27+
print(' Error : {}'.format(err))
28+
29+
```
30+
31+
输出的结果:
32+
33+
```txt
34+
35+
False True
36+
False True
37+
Error : '<' not supported between instances of 'User' and 'User'
38+
39+
```
40+
41+
可以看看最后的输出结果,报了个异常,那是因为大于和小于比较运算符引发 TypeError 异常。也就是 `Enum` 类的枚举是不支持大小运算符的比较的。
42+
43+
那么能不能让枚举类进行大小的比较呢?
44+
45+
当然是可以的,使用 IntEnum 类进行枚举,就支持比较功能。
46+
47+
```python
48+
#!/usr/bin/env python3
49+
# -*- coding: UTF-8 -*-
50+
import enum
51+
52+
53+
class User(enum.IntEnum):
54+
Twowater = 98
55+
Liangdianshui = 30
56+
Tom = 12
57+
58+
59+
try:
60+
print('\n'.join(s.name for s in sorted(User)))
61+
except TypeError as err:
62+
print(' Error : {}'.format(err))
63+
64+
65+
```
66+
67+
看看输出的结果:
68+
69+
```txt
70+
Tom
71+
Liangdianshui
72+
Twowater
73+
```
74+
75+
通过输出的结果可以看到,枚举类的成员通过其值得大小进行了排序。也就是说可以进行大小的比较。

python11/Preface.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# 前言 #
2+
3+
虽然没多少阅读,可是还是坚持写下去。对 Python 感兴趣的童鞋可以加入 Python 学习讨论微信群喔。可以先加我微信,然后拉进群。本人微信:
4+
5+
![微信](http://img.blog.csdn.net/20170626191709373?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvVHdvX1dhdGVy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
6+
7+
# 目录 #
8+
9+
![草根学Python(十一) 枚举类](https://user-gold-cdn.xitu.io/2017/8/28/e403eb0edf80f951450edfef8e306a2f)

0 commit comments

Comments
 (0)