文章目录
- 枚举
- 比较运算
- 枚举转换
- 小结
- 一切皆对象
- 什么是闭包
- 闭包的经典误区
- 用非闭包解决问题
- 再用闭包解决问题
- lambda表达式
- 三元表达式
- map
- reduce
- filter
- 装饰器(类似C#中的特性)
枚举
Python2里面是没有枚举的,但在Python3里面枚举是新加的
枚举其实是一个类
首先需要导入enum下的Enum,需要类继承Enum
打印枚举的值,显示的是他的标签,而不是他具体的数值
可以通过枚举点value来获取枚举的值
通过枚举点name来获取枚举的标签
枚举点name是返回一个字符串类型
枚举直接打印出来是一个枚举类型
比较运算
枚举和具体的值比较,即使值是相等的,也会返回false
枚举不能比较大小,会报错
枚举可以使用is身份运算
枚举转换
直接类名(参数是一个具体的值),VIP(a)就可以得到a这个值对应的枚举类型是什么
小结
类继承Enum,枚举的值可以是一个字符串,如果不想枚举的值只能是一个int值,就要继承IntEnum
给枚举加上装饰器@unique,可以限制枚举定义相同的值,这样定义会报错
一切皆对象
在其他语言中函数并不是一个对象,只是一段可执行的代码,在Python中函数却是一个对象,而且你可以认为在Python里面所有的东西都是对象。
什么是闭包
这段代码执行不会报错,所以得出的结论是函数是可以作为返回值返回的
函数是可以赋值给一个变量的
直接变量后面跟一个括号就可以执行这个变量所赋值的函数了
闭包等于函数加上环境变量
上图的代码,执行f(2)的值还是100,而不是40,原因是因为,闭包只会去定义时候的值
__closure __返回一个闭包对象
__closure __【0】.cell_contents 返回环境变量
闭包的经典误区
上图的代码,在f2函数里面,只要有a=20,就不是一个闭包,因为f2里面的a被Python认为是一个局部变量,而不是外面的环境变量a,而闭包必须是函数加环境变量共同组成的语句块
用非闭包解决问题
上面这段代码执行起来会报错
而把origin = new_pos去掉将不会报错
为什么?
因为只要origin在等号左边,Python就会认为origin是一个局部变量
所以当 new_pos = origin + step这句代码的时候,会报origin没有定义的错误
而用global关键字声明origin是一个全局变量就可以解决上面的问题了
再用闭包解决问题
这边不用全局变量,而用 nonlocal 关键字表示这个pos变量不是局部变量
lambda表达式
lambda表达式的定义如上图所示
lambda只能后面接上一个表达式,如果写一个完整的语句会报错
三元表达式
三元表达式的定义如上图所示
map
map是一个函数,第一个参数是一个方法,第二个参数是一个列表。
可以把map函数的作用看成,把列表的值做第一个参数方法的参数,结果是这个方法的返回结果,可以用list把结果map 对象转换成一个列表。
如果你想传两个参数,可以传递两个列表
如果其中一个列表有缺失,结果也会少了缺失的部分,如上图的运行结果只有前六个有结果,由于7,8的缺失,结果也会缺失。
reduce
reduce是一个连续计算的结果,而上面这段代码执行结果是36,是这八位数相加的结果。
为什么是这个结果呢?
因为reduce是一个连续的计算结果,所以执行顺序是下面的顺序。
首先拿1,2作为lambda表达式的参数x,y,结果是3,然后结果3作为下次计算的x,y取列表中的3,所以结果相加是6,6也会继续作为下次计算结果的参数x,以此类推
而第三个参数是作为初始值传入第一次调用lambda的调用中,如上图所示
filter
filter适合一些需要过滤的场景中,上图的例子可以过滤掉不是1的数字
装饰器(类似C#中的特性)
import time
def decorator(func):
def wrapper():
print(time.time())
func()
return wrapper
@decorator
def f1():
print('This is a function')
f1()
# 打印结果
#1585625939.49
#This is a function
这个我们自己定义的装饰器,在没有改变原f1函数的定义的代码,和f1调用逻辑的代码前提下,给f1添加了新的功能。不过是因为@加上装饰器。
f = decorator(f1)
f()
如果不用@符号 ,我们需要这样才可以使用装饰器修饰和调用原函数。
那如果f1函数有参数怎么办,或者这个装饰器还可能给很多参数的别的函数用,那我们装饰器需要做那些改动?
import time
def decorator(func):
def wrapper(*args):
print(time.time())
func(*args)
return wrapper
@decorator
def f1(name):
print('This is a function'+name)
@decorator
def f2(name1,name2):
print('This is a function '+name1+' '+name2)
f1('test')
f2('name1','name2')
上图的装饰器只是用了可变参数来解决这个问题
然后如果现在有f3有一个可变的关键字参数,上面的这个装饰器就不能满足了,所以用到下面的这种写法
import time
def decorator(func):
def wrapper(*args,**kw):
print(time.time())
func(*args,**kw)
return wrapper
@decorator
def f1(name):
print('This is a function'+name)
@decorator
def f2(name1,name2):
print('This is a function '+name1+' '+name2)
@decorator
def f3(name1,name2,**kw):
print('This is a function '+name1+' '+name2)
print(kw)
f1('test')
f2('name1','name2')
d = {'a':1,'b':2,'c':3}
f3('name1','name2',a=1,b=2,c=3)
f3('name1','name2',**d)
我们也给装饰器加上一个可变的关键字参数就好了