11-1 枚举其实是一个类
# 11-1 枚举其实是一个类
# 类型
绿钻 、黄钻、 红钻、 黑钻
1 绿钻
2 黄钻
3 红钻
4 黑钻
# 字典不是最优的表示方法。下面看看枚举可以表示各种各样的类型!
from enum import Enum
class VIP(Enum):#继承Python给我们提供的enum类
YELLOW = 1
GREEN = 2
BLACK = 3 #枚举的标识名字大写
RED = 4
print(VIP.YELLOW)
# 打印结果如图1,不是1!!!这就是枚举的意义重点在于标识标签不是数字
11-2 枚举和普通类相比有什么优势
# 11-2 枚举和普通类相比有什么优势
# 第一种形式类变量
yellow = 1
green = 2
# 第二种字典形式 :
{'yellow':1,'green':2}
# 第三种形式 用类
class TypeDiamond():
yellow = 1
green = 2
# 以上三种形式都有一个共同的缺陷:第一就是可变,第二,没有防止相同值得功能(比如不同的标签出现相同标签的功能)
11-3 枚举类型、枚举名称与枚举值
# 11-3 枚举类型、枚举名称与枚举值
# Q1:如何获得每一个标签下面所对应的数值
from enum import Enum
class VIP(Enum):
YELLOW = 1
BLACK = 3
RED = 4
# 别名
class common():
YELLOE = 1
print(VIP.YELLOW.value)#通过点value的形式打印标签的对应值
# 打印结果如图1
# Q2:如何获得每一个值下面所对应的标签
from enum import Enum
class VIP(Enum):
YELLOW = 1
BLACK = 3
RED = 4
# 别名
class common():
YELLOE = 1
print(VIP.YELLOW.name)#通过点name的形式打印数值对应的标签
# 打印结果如图2
# 看看下面的打印类型
from enum import Enum
class VIP(Enum):
YELLOW = 1
BLACK = 3
RED = 4
# 别名
class common():
YELLOE = 1
print(type(VIP.YELLOW.name))#看看这两个的不同
print(type(VIP.YELLOW))
print(VIP['RED'])
#打印结果如图3和图5,第一个是字符串类型,第二个是枚举类型
# 枚举类型(通过名称可以获得枚举类型)、枚举的值(1,2,3,4)、枚举的名字(标签的名字)
# 枚举是可以用来遍历的
from enum import Enum
class VIP(Enum):
YELLOW = 1
BLACK = 3
RED = 4
# 别名
class common():
YELLOE = 1
for v in VIP:#for循环的遍历
print(v)
#打印结果如图4
11-4 枚举的比较运算
# 11-4 枚举的比较运算
from enum import Enum
class VIP(Enum):
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
# 别名
class common():
YELLOE = 1
result = VIP.GREEN == VIP.BLACK
print(result)
# 打印结果如图1
from enum import Enum
class VIP(Enum):
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
# 别名
class common():
YELLOE = 1
result = VIP.GREEN > VIP.BLACK#枚举不支持大小比较
print(result)
# 打印结果如图2
from enum import Enum
class VIP(Enum):
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
# 别名
class common():
YELLOE = 1
# result = VIP.GREEN > VIP.BLACK
result = VIP.GREEN is VIP.GREEN
print(result)
# 打印结果如图3
from enum import Enum
class VIP(Enum):
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
class VIP1(Enum):
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
# 别名
class common():
YELLOE = 1
result = VIP.GREEN == VIP1.GREEN
print(result)
# 打印结果如图4,打印的结果是false,虽然数值相同,但是不是同一个枚举
11-5 枚举注意事项
# 11-5 枚举注意事项
from enum import Enum
class VIP(Enum):
YELLOW = 1
GREEN = 1#如果两个数值一样,打印的结果会是什么?
BLACK = 3
RED = 4
# 别名
class common():
YELLOE = 1
print(VIP.GREEN)
# 打印结果如图1,并不会报错,只是会打印出来YELLOW,原因如下:
from enum import Enum
class VIP(Enum):
YELLOW = 1
YELLOW_ALIAS = 1#如果两个数值一样,第二个GREEN,将成为第一个YELLOW的别名!!附属
BLACK = 3
RED = 4
class common():
YELLOE = 1
print(VIP.GREEN)
# 看看遍历下面的注意事项
from enum import Enum
class VIP(Enum):
YELLOW = 1
YELLOW_ALIAS = 1#如果两个数值一样,第二个GREEN,将成为第一个YELLOW的别名!!附属
BLACK = 3
RED = 4
class common():
YELLOE = 1
for v in VIP:
print(v)
# 打印结果如图2所示,只打印了3个,别名是不会打印出来的
# 那么如果想要打印出来别名怎么办?
from enum import Enum
class VIP(Enum):
YELLOW = 1
YELLOW_ALIAS = 1
BLACK = 3
RED = 4
class common():
YELLOE = 1
for v in VIP.__members__.items():#内置__members__变量属性下面的items方法
print(v)
# 打印结果如图3所示,只打印了4个,别名是会打印出来的
# (还有一种方法)那么如果想要打印出来别名怎么办?
from enum import Enum
class VIP(Enum):
YELLOW = 1
YELLOW_ALIAS = 1
BLACK = 3
RED = 4
class common():
YELLOE = 1
for v in VIP.__members__:#直接使用内置__members__变量属性即可
print(v)
# 打印结果如图4所示,只打印了4个,别名是会打印出来的
11-6 枚举转换
# 在数据库中建议使用数字的形式来存储,省内存还方便(数字的形式来代表类型)
# 下面看看在代码里使用数字来代表枚举类型
from enum import Enum
class VIP(Enum):
YELLOW = 1
YELLOW_ALIAS = 1
BLACK = 3
RED = 4
class common():
YELLOE = 1
if a==1: #这种形式的代码可读性不是很强
print()
if a==2:
print()
for v in VIP.__members__:#直接使用内置__members__变量属性即可
print(v)
# 看看这种可读性强一点的代码
from enum import Enum
class VIP(Enum):
YELLOW = 1
YELLOW_ALIAS = 1
BLACK = 3
RED = 4
class common():
YELLOE = 1
if a==VIP.YELLOW: #这种形式的代码可读性很强
print()
if a==VIP.BLACK:
print()
for v in VIP.__members__:#直接使用内置__members__变量属性即可
print(v)
# 如何把数字转换成枚举类型?
from enum import Enum
class VIP(Enum):
YELLOW = 1
YELLOW_ALIAS = 1
BLACK = 3
RED = 4
class common():
YELLOE = 1
a = 1 #通过这种方式就可以进行转换了,使用具体的数值来访问枚举类型的方案
print(VIP(a))
# 打印结果如图1
11-7 枚举小结
# 11-7 枚举小结
from enum import Enum
from enum import IntEnum
class VIP(IntEnum):
YELLOW = 1
GREEN = 'str' #如果枚举类型下面都是数字类型,不允许出现字符串。可以使用IntEnum
BLACK = 3
RED = 4
# 如果出现相同的数值怎么办?
from enum import Enum
from enum import IntEnum,unique
@unique
class VIP(IntEnum):
YELLOW = 1
GREEN = 1 #如果出现两个相同的数字,我们不希望出现别名,希望他报错,那么可以采用@unique(装饰器)
BLACK = 3
RED = 4
# 打印结果如图1
# 23种设计模式,枚举是单例模式,在Python中不要实例化
11-8 进阶内容开场白
1.业务逻辑的开发者,不考虑太多的封装性
2.包、类的开发者
11-9 一切皆对象
# 11-9 一切皆对象
# 函数式编程(淡化这个概念)
# 闭包的概念
# 学习函数,是为了上面两个
# 函数只是一段可以执行的代码,并不是对象。不能实例化,而对象可以实例化
# Python里一切都是对象
# 在Python里,另外一个函数的参数,传递到另外的函数里
# 在Python里,把一个函数当做另外一个函数的返回结果
def a():
pass
print(type(a))
# 打印结果如图1,是一个类
11-10 什么是闭包
# 11-10 什么是闭包
def curve_pre():#抛物线函数
def curve():
pass
curve()#这时候调用curve不可以,因为它在函数里面,属于内部函数
# 打印结果如图1
def curve_pre():
def curve():
print('this is a function')
pass
return curve #这个肯定可以返回,函数作为一个返回结果,被另一个函数给返回回来的
f = curve_pre()#可以把函数赋值给另外一个变量!!
f()
# 打印结果如图2
def curve_pre():
a = 25
def curve(x):
return a*x*x
return curve #这个肯定可以返回,函数作为一个返回结果,被另一个函数给返回回来的
f = curve_pre()#可以把函数赋值给另外一个变量!!
print(f(2))
# 打印结果如图3
# 看看下面的执行结果,结果是多少?
def curve_pre():
a = 25
def curve(x):
return a*x*x
return curve
a = 10
f = curve_pre()#
print(f.__closure__)#闭包的结果存放的地方
print(f.__closure__[0].cell_contents)
# 此时f(2) = curve_pre()
print(f(2))
# 打印结果如图4,为什么结果是100不是40?
# 闭包 = 函数+环境变量
# 闭包和全局变量是有区别的!!
a = 25 #全局变量
def curve_pre():
def curve(x):
return a*x*x
return curve
a = 10
f = curve_pre()#可以把函数赋值给另外一个变量!!
# 此时f(2) = curve_pre()
print(f(2))
# 打印结果如图5
11-11 一个事例看看闭包
11-12 闭包的经典误区
# 11-11 一个事例看看闭包
# 11-12 闭包的经典误区
# 闭包 = 函数+环境变量(定义时候的变量)
# 不仅有返回值,而且还有现场
def curve_pre():
a = 25
def curve(x):
return a*x*x
return curve
a = 10
f = curve_pre()
print(f.__closure__)#闭包的结果存放的地方
print(f.__closure__[0].cell_contents)
print(f(2))
# 看看下面代码,理解意义
def f1():
a = 10
def f2():
# 此时将被Python认为是一个局部变量
a = 20
print(a)
print(a)
f2()
print(a)
f1()
# 打印结果如图1,上述代码执行的时候,一定是由外到里。想想打印结果!!!
# 看看下面的闭包的形式!!!
def f1():
a = 10
def f2():
# 此时将被Python认为是一个局部变量
a = 20
return a
return f2
f = f1()
print(f)
f1(f.__closure__)
# 这种情况不属于闭包,a = 20,并没有引用外部变量。所以不是闭包只是会被当成局部变量。
# 第二个函数里的a,一定要去引用,不能去赋值。否则就不是闭包
11-13 出个题,用闭包解决!
11-14 先用非闭包的方法解决
11-15 再用闭包解决一下_
# 11-13 出个题,用闭包解决!
# 11-14 我先用非闭包解决一下
# 11-15 再用闭包解决一下_
# 计算旅行者所走的步数
origin = 0
def go (step):
new_pos = origin + step
origin = new_pos
return origin
print(go(2))
print(go(3))
print(go(6))
# 上述过程是错误的,结果会报错。将origin = new_pos注释掉,打印的结果,全部是0。想想这个结果为什么不行,错在哪里?
# 怎么改写?会有正确的结果
origin = 0
def go (step):
global origin#声明一下全局变量
new_pos = origin + step
origin = new_pos
return origin
print(go(2))
print(go(3))
print(go(6))
# 打印结果如图1.正确的结果
# 11-15 再用闭包解决一下_
origin = 0
def factory(pos):
def go(step):
nonlocal pos#声明一下,不是局部变量用nonlocal
new_pos = pos + step
pos = new_pos
return new_pos
return go
tourist = factory(origin)
print(tourist(2))
print(tourist.__closure__[0].cell_contents)#打印看看是不是闭包在起作用
print(tourist(3))
print(tourist.__closure__[0].cell_contents)
print(tourist(6))
print(tourist.__closure__[0].cell_contents)
作者:buaishengqi
链接:https://www.jianshu.com/p/5dd0601d105c
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。