十一、python的高级语法与用法
一、枚举其实是一个类
现实世界中的“类型”,在计算机世界中如何描述?
常见的
1)用1、2、3..等数字表示类型
2)较好的做法是用字典表示
3)最好的是使用枚举
# coding=utf-8
from enum import Enum class VIP(Enum): # 继承Enum类
YELLOW = 1 # 枚举类型建议使用大小
GREEN = 2
BLACK = 3
RED = 4 print(VIP.YELLOW)
1、python中,枚举的本质是类
2、使用时需要继承Enum类
3、类中定义一组常量,建议使用全大写字母表示
4、数字1、2、3其实没有意义,枚举的意义重在标识,不在取值。
二、枚举与普通类相比的优势
如果不使用枚举,如何表示类型
1)使用模块中的全局变量
yellow=1
green=2
2) 字典
{‘yellow’:1,'green':2}
3) 普通类
class TypeDiamond():
yellow=1
green=2
缺点:
1)可变,即可以在代码中轻易改变
2)没有防止相同标签的功能
现实中的‘类型’一旦定义不应该被轻易更改,但字典可以通过赋值改变类型,同样普通类也可以轻易改变类型。
字典和普通类允许变量(类型)相同
{‘yellow’:1,'yellow:2}
在python中没有真正的常量,在枚举中定义的类型不能被更改,且不能取相同的标记。
1)枚举的保护性
2)枚举的防重性
三、枚举类型、枚举名称与枚举值
1、获取某个枚举标签的值.value
2、获取某个枚举标签的名字.name
3、通过枚举标签的名称获取枚举的类型
4、枚举可遍历
# 获取枚举标签的值
print(VIP.YELLOW.value)
# 获取枚举标签的名字
print(VIP.YELLOW.name)
# 获取枚举类型
print(VIP.YELLOW)
for v in VIP:
print(v)
1 枚举值
YELLOW 枚举名称
VIP.YELLOW 枚举类型
四、枚举之间的比较
枚举支持的比较
1)等值比较
res=VIP.YELLOW==VIP.GREEN
print(res) 打印结果:False
2)身份比较
res=VIP.YELLOW is VIP.YELLOW
print(res)
打印结果:True
枚举不支持的比较
1)名称和值的比较
class VIP(Enum):
YELLOW = 1 # 枚举类型建议使用大小
GREEN = 2
BLACK = 3
RED = 4 res=VIP.YELLOW ==1
print(res)
打印结果:False
2)大小比较
res=VIP.YELLOW <VIP.GREEN
print(res)
报错:TypeError: '<' not supported between instances of 'VIP' and 'VIP'
3)枚举类之间的比较
class VIP(Enum):
YELLOW = 1 # 枚举类型建议使用大小
GREEN = 2
BLACK = 3
RED = 4 class VIP1(Enum):
YELLOW = 1 # 枚举类型建议使用大小
GREEN = 2
BLACK = 3
RED = 4 res=VIP.YELLOW ==VIP1.YELLOW
print(res)
打印结果:False 五、枚举注意事项
1、不能使用相同的标签
2、取值可以相同,但会作为别名,不能作为独立的枚举类型
3、枚举的遍历,取值相等时,不打印(无法访问)别名
# coding=utf-8
from enum import Enum class VIP(Enum):
YELLOW = 1 # 枚举类型建议使用大小
YELLOW2 = 1
BLACK = 3
RED = 4 for v in VIP:
print(v)

4、如何遍历(访问)别名?VIP.__members__
# coding=utf-8
from enum import Enum class VIP(Enum):
YELLOW = 1 # 枚举类型建议使用大小
YELLOW2 = 1
BLACK = 3
RED = 4 for v in VIP.__members__:
print(v)

六、枚举的转换
1、将枚举类型转化为数字
实际编码过程中,推荐:在代码中定义枚举类型,数据库中存储枚举值,通过枚举名称访问数据库中的枚举值
if a==VIP.YELLOW:#不推荐使用a==1
print(...)
if a==VIP.GREEN:#不推荐使用a==2
print(...)
2、将数字转化为枚举类型
a=1
print(VIP(a))
# coding=utf-8
from enum import Enum class VIP(Enum):
YELLOW = 1 # 枚举类型建议使用大小
YELLOW2 = 1
BLACK = 3
RED = 4 a=1
print(VIP(a))
七、枚举小结
1、IntEunm类
枚举值可以是int类型,也可以是str类型,如果明确了是int类型,可以使用IntEunm类,该类限制了枚举值只能是int
#coding=utf-8
from enum import IntEnum class VIP(IntEnum):
YELLOW = 'a' # 枚举类型建议使用大小
YELLOW2 = 1
BLACK = 3
RED = 4

2、限制别名(不能取相同值)
#coding=utf-8
from enum import IntEnum,unique @unique
class VIP(IntEnum):
YELLOW = 1 # 枚举类型建议使用大小
YELLOW2 = 1
BLACK = 3
RED = 4

3、枚举在python中是单例模式,不能实例化
这里引入了设计模式的概念,其中单例模式是23种设计模式中的一种。
八、函数式编程、闭包导论
1、python支持函数式编程,该用的时候用
2、概念不重要,重要的是思维
3、函数:其他语言中函数是指一段可执行的代码,并不是对象,但在python中,函数就是对象,可实例化
#coding=utf-8 def a():
pass print(type(a))

python:一切皆对象
那么
- 函数可以赋值给变量
- 函数可作为另一个函数的参数
- 函数可作为另一个函数的返回结果
九、什么是闭包
闭包=函数+环境变量
环境变量:函数定义时用到的变量(在函数外)
# coding=utf-8 def curve_pre(): # 闭包
a = 25 # 环境变量 def curve(x): # 函数
return a * x * x #引用环境变量a return curve # 返回函数 f = curve_pre()
print(f(2))
结果:100
对a重新赋值,结果如何?
# coding=utf-8 def curve_pre(): # 闭包
a = 25 # 环境变量 def curve(x): # 函数
return a * x * x #引用环境变量a return curve # 返回函数 a=10
f=curve_pre()
print(f(2))
结果仍然是:100
如何获取环境变量的值25
# coding=utf-8 def curve_pre(): # 闭包
a = 25 # 环境变量 def curve(x): # 函数
return a * x * x #引用环境变量a return curve # 返回函数 f = curve_pre()
#获取环境变量的值
print(f.__closure__[0].cell_contents)
十、一个事例看闭包
闭包的意义:保存环境,现场
局部变量不影响外部的环境变量
# coding=utf-8 def f1():
a = 10 def f2():
a = 20
print(a) print(a)
f2()
print(a) f1()
打印结果:
10
20
10
十一、闭包的经典误区
代码1
#coding=utf-8 def f1():
a=10
def f2():
a=20 #a出现在表达式的作为,会被当做局部变量 f=f1()
print(f.__closure__)
打印结果:
Traceback (most recent call last):
File "E:/pyClass/eleven/c11.py", line 9, in <module>
print(f.__closure__)
AttributeError: 'NoneType' object has no attribute '__closure__'
原因:
f1()不是闭包,因为没有返回?
代码2:加入返回
# coding=utf-8 def f1():
a = 10 def f2():
a = 20 # a出现在表达式的作为,会被当做局部变量 return f2 f = f1()
print(f.__closure__)
打印结果:None
原因:函数f2没有返回?
代码3:在f2中增加返回
# coding=utf-8 def f1():
a = 10 def f2():
a = 20 # a出现在表达式的作为,会被当做局部变量
return a
return f2 f = f1()
print(f.__closure__)
打印结果:None
原因:f2中没有引用环境变量
代码4
# coding=utf-8 def f1():
a = 10 def f2():
# a = 20 # a出现在表达式的作为,会被当做局部变量
return a
return f2 f = f1()
print(f.__closure__)
打印结果:(<cell at 0x00000000006CA5E8: int object at 0x000000001DCEB560>,)
总结
1)环境变量不能作为局部变量被赋值
2)需要返回函数
3)函数需要引用环境变量
十二、几个问题,用闭包解决
问题:计算旅行者当前位置,假设起点x=0,每走一步,x+1
问题关键:保存上次结果
起点:x=0
每走一步:x+1
3步:result=3
5步:result=8
6步:result=14
方法一:非闭包
#coding=utf-8 origin=0 def go(step):
new_pos=origin+step
origin=new_pos
return origin print(go(2))
print(go(3))
print(go(5))
报错信息:
Traceback (most recent call last):
File "E:/pyClass/eleven/c12.py", line 10, in <module>
print(go(2))
File "E:/pyClass/eleven/c12.py", line 6, in go
new_pos=origin+step
UnboundLocalError: local variable 'origin' referenced before assignment
原因:第7行中,origin出现在表达式左边,会被认为是局部变量,局部变量在6行中没有定义就使用,系统认为是错误的
尝试解决:
注释掉第7行,不再报错,但是打印结果
0
0
0
与预期不符
最终解决:使用global关键字,声明origin为全局变量
#coding=utf-8 origin=0
def go(step):
global origin
new_pos=origin+step
origin=new_pos
return origin print(go(2))
print(go(3))
print(go(5))
打印结果
2
5
10
方法二:使用闭包
# coding=utf-8 origin = 0 def factory(pos):
def go(step):
nonlocal pos # 声明pos非局部变量
new_pos = pos + step
pos = new_pos
return pos return go tourist = factory(origin)
print("旅行者当前位置:%s" % (tourist(2)))
print("origin变量的值:%s" % (origin))
print("环境变量的值:%s" % (tourist.__closure__[0].cell_contents))
print("旅行者当前位置:%s" % (tourist(3)))
print("origin变量的值:%s" % (origin))
print("环境变量的值:%s" % (tourist.__closure__[0].cell_contents))
print("旅行者当前位置:%s" % (tourist(5)))
print("origin变量的值:%s" % (origin))
print("环境变量的值:%s" % (tourist.__closure__[0].cell_contents))
打印结果:
旅行者当前位置:2
origin变量的值:0
环境变量的值:2
旅行者当前位置:5
origin变量的值:0
环境变量的值:5
旅行者当前位置:10
origin变量的值:0
环境变量的值:10
总结
1)origin并没有被改变
2)pos环境变量被记住
十一、python的高级语法与用法的更多相关文章
- Python(九) Python的高级语法与用法
本章节我们揭开Python进阶部分的高级特性,详细讲解枚举.闭包,并对函数式编程做出介绍 一. 枚举其实是一个类 from enum import Enum #枚举类 class VIP(Enum): ...
- 12.Python的高级语法和用法
# from enum import Enum # 枚举 # class VIP(Enum): # YELLOW = # YELLOW_ALIAS = # 别名 # GREEN = # BLACK = ...
- python 类高级语法 静态方法
通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方 ...
- Python自动化 【第七篇】:Python基础-面向对象高级语法、异常处理、Scoket开发基础
本节内容: 1. 面向对象高级语法部分 1.1 静态方法.类方法.属性方法 1.2 类的特殊方法 1.3 反射 2. 异常处理 3. Socket开发基础 1. ...
- Python高级语法之:一篇文章了解yield与Generator生成器
Python高级语法中,由一个yield关键词生成的generator生成器,是精髓中的精髓.它虽然比装饰器.魔法方法更难懂,但是它强大到我们难以想象的地步:小到简单的for loop循环,大到代替多 ...
- python 循环高级用法 [expression for x in X [if condition] for y in Y [if condition] ... for n in N [if condition] ]按照从左至右的顺序,分别是外层循环到内层循环
高级语法 除了像上面介绍的 [x ** 2 for x in L] 这种基本语法之外,列表推导式还有一些高级的扩展. 4.1. 带有if语句 我们可以在 for 语句后面跟上一个 if 判断语句,用于 ...
- 从一知半解到揭晓Java高级语法—泛型
目录 前言 探讨 泛型解决了什么问题? 扩展 引入泛型 什么是泛型? 泛型类 泛型接口 泛型方法 类型擦除 擦除的问题 边界 通配符 上界通配符 下界通配符 通配符和向上转型 泛型约束 实践总结 泛型 ...
- 进击的Python【第七章】:Python的高级应用(四)面向对象编程进阶
Python的高级应用(三)面向对象编程进阶 本章学习要点: 面向对象高级语法部分 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 一.面向对象高级语法部分 静态方法 ...
- 进击的Python【第六章】:Python的高级应用(三)面向对象编程
Python的高级应用(三)面向对象编程 本章学习要点: 面向对象编程介绍 面向对象与面向过程编程的区别 为什么要用面向对象编程思想 面向对象的相关概念 一.面向对象编程介绍 面向对象程序设计(英语: ...
随机推荐
- 使用electron静默打印
1.使用electron打印的理由 很多情况下程序中使用的打印都是用户无感知的.并且想要灵活的控制打印内容,往往需要借助打印机给我们提供的api再进行开发,这种开发方式非常繁琐,并且开发难度较大. e ...
- 从mediaserver入手快速理解binder机制(最简单理解binder)【转】
本文转载自;https://blog.csdn.net/u010164190/article/details/53015194 Android的binder机制提供一种进程间通信的方法,使一个进程可以 ...
- POSTGRESQL 导入导出
安装postgresql yum install postgresql postgresql-server mysql占用端口3306 pgsql是5432 2 导入整个数据库 psql -U pos ...
- [原创]java操作word生成水印
应用场景 为了保护版权或辨别文件的真伪,有时需要在生成的Word文件中动态添加水印,PageOffice组件的WaterMark类就封装了给在线编辑的Word文件添加水印这一功能,调用接口非常简单. ...
- codeforces 659A A. Round House(水题)
题目链接: A. Round House time limit per test 1 second memory limit per test 256 megabytes input standard ...
- android自定义控件(四) View中的方法
onFinishInflate() 当View中所有的子控件 均被映射成xml后触发 onMeasure(int, int) 确定所有子元素的大小 onLayout(boolean, int, int ...
- bzoj 2850: 巧克力王国 K-D树
题目大意 http://www.lydsy.com/JudgeOnline/problem.php?id=2850 题解 对于每个人,我们发现它能够接受的巧克力中 如果对参数分别讨论,那么一定是一个连 ...
- AI-Info-Micron-Insight:通往完全自主之路
ylbtech-AI-Info-Micron-Insight:通往完全自主之路 1.返回顶部 1. 通往完全自主之路 自动驾驶汽车正在从未来梦想演变为当代现实,随着技术成熟,个人和公共交通将永远转变. ...
- Python中datetime的使用和常用时间处理
datetime在python中比较常用,主要用来处理时间日期,使用前先倒入datetime模块.下面总结下本人想到的几个常用功能. 1.当前时间: >>> print dateti ...
- SQL Replication
http://www.cnblogs.com/CareySon/archive/2012/06/20/IntroductToSQLServerReplicationPart1.html http:// ...