今日内容:
1.装饰器
2.内置函数
1.装饰器
对现有函数不进行任何修改的进行功能扩展。
开放封闭原则:
1.对扩展开放
2.对修改封闭(不修改源代码)
3.不改变之前的调用方式
简单版装饰器:
# 装饰器的目的是不修改源代码的基础上扩展新功能 # 源代码 def content(): print("程序的主体内容") # 新扩展的功能 def Login(func): # func 指向 content函数的内存地址 def inner(): print("登陆!") func() # 真正的执行原函数content() return inner # 返回inner的内存地址 content = Login(content) # Login函数调用后得到inner函数的内存地址,content指向inner content() # 执行content( inner )函数
import time def func(a,b): print("旧功能") print(a if a > b else b) time.sleep(1) def wrapper(f): def inner(*args,**kwargs): # 接收多个参数 print("新功能") start = time.time() f(*args,**kwargs) print("执行时间:%s."%(time.time()-start)) return inner func = wrapper(func) func(10,20) """ 新功能 旧功能 20 执行时间:1.000023603439331. """
语法糖版本:
import time def wrapper(f): def inner(*args,**kwargs): print("新功能") start = time.time() f(*args,**kwargs) print("执行时间:%s."%(time.time()-start)) return inner @wrapper # func = wrapper(func) def func(a,b): print("旧功能") print(a if a > b else b) time.sleep(1) func(10,20)
套了多层装饰器:
import time def wrapper(f): def inner(*args,**kwargs): print(1) print("新功能") start = time.time() f(*args,**kwargs) print("执行时间:%s."%(time.time()-start)) return inner def wrapper2(f): def inner(*args,**kwargs): print(2) print("新功能") start = time.time() f(*args,**kwargs) print("执行时间:%s."%(time.time()-start)) return inner def wrapper3(f): def inner(*args,**kwargs): print(3) print("新功能") start = time.time() f(*args,**kwargs) print("执行时间:%s."%(time.time()-start)) return inner # wrapper3 包着 wrapper2 包着 wrapper 包着 原func @wrapper3 # func = wrapper3(func) # 新func --> wrapper3 : inner --> wrapper2 : inner --> wrapper : inner --> 原func @wrapper2 # func = wrapper2(func) # 新func --> wrapper2 : inner --> wrapper : inner --> 原func @wrapper # func = wrapper(func) # 新func -- > wrapper : inner --> 原func def func(a,b): print("旧功能") print(a if a > b else b) time.sleep(1) # func = wrapper(func) # func = wrapper2(func) # func = wrapper3(func) func(10,20) """ 3 新功能 2 新功能 1 新功能 旧功能 20 执行时间:1.000126838684082. 执行时间:1.000126838684082. 执行时间:1.000126838684082. """
需要查询原函数信息需要用到:wraps()
# 装饰器----对原函数操作 import time from functools import wraps def wrapper(f): @wraps(f) # 返回正确的函数名的内容 def inner(*args,**kwargs): print("新功能") start = time.time() f(*args,**kwargs) print("执行时间:%s."%(time.time()-start)) return inner @wrapper # 相当于 func = wrapper(func) def func(a,b): """ 原func的注释。 """ print("旧功能") print(a if a > b else b) time.sleep(1) print(func.__name__) print(func.__doc__) func(10,20) """ func #不用@wraps() 返回的内容为inner 原func的注释。 新功能 旧功能 20 执行时间:1.0000817775726318. """
动态使用装饰器:
from functools import wraps import time def test(flag): def wrapper(func): if flag: @wraps(func) def inner(*args,**kwargs): print("新功能") result = func(*args,**kwargs) return result return inner else: return func return wrapper # False 表示不使用装饰器功能,True表示使用 @test(True) # 相当于 func = test(False)(func) def func(): print("旧功能") time.sleep(1) return 1 print(func()) print(func.__name__)
2.内置函数
重要的:
1.dir() # 可以用在查看一个数据的可用方法
例:
print([i for i in dir(list) if not i.startswith('_')]) # ['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
2.enumerate() # 枚举,可以用在同时得到列表索引和元素
例:
li = [i for i in 'abcde'] for index, element in enumerate(li): print("%s : %s"%(index , element)) """ 0 : a 1 : b 2 : c 3 : d 4 : e """
3.id() # 查看数据的内存地址,用来看数据是否是相同的内存地址。
4.input() # 获取用户输入内容,输入的数据 类型是字符串。
5.int() # 把数据转成整型,如果不为数字会抛出ValueError
6.isinstance(value,type) # 判断该value是否是该type
print(isinstance([1,2],list)) # True
7.len(iterable) # 获取可迭代对象长度
8.list() # 把一个可迭代对象转成列表数据类型
9.max()和min() # 返回列表中或元素中最大值或最小值,key可以接收函数
指定key使用:
dic = {1:321,2:123} ret = max(dic,key=lambda x:dic[x]) print(ret) # 1
10.print() # 打印内容
11.repr() # 元素如果是字符串,会有引号看到
12.reversed() # 反转内容,不是在原列表的基础上改动
print(list(reversed([1,2,3]))) # [3, 2, 1]
reversed的坑: # 返回的是一个迭代器,迭代器的特性是一次性
a = [1,2,3,4,5] t = reversed(a) print(t) # <list_reverseiterator object at 0x00000241E317C198> print(list(t)) # [5, 4, 3, 2, 1] print(list(t)) # []
13.round() # 四舍五入,默认不保留小数位,可以指定保留小数位数
print(round(5.5)) # 6 print(round(5.2856,2)) # 5.29
round的坑: # 为偶数的,小数为.5的不进位
print(round(1.5)) print(round(2.5)) print(round(3.5)) print(round(4.5)) ''' 2 2 4 4 '''
14.sum() # 求和,传入一个数组,如果为字典,只是key的总和,且key都必须是数字
15.zip() # 以最短的可迭代对象进行组合
li = [1,2,3] li2 = ['a','b','c','d'] li3 = [i for i in zip(li,li2)] print(li3) # [(1, 'a'), (2, 'b'), (3, 'c')]
复杂一点的内置函数:
16.lambda # 匿名函数,只能用于简单需求
格式: lambda 参数:返回值
f = lambda x,y:x if x > y else y print(f(10,20)) # 20 # 拆分后的格式 def f(x,y): if x > y: return x else: return y print(f(10,20))
17.sorted() # 排序
一般用法:
# 默认reverse=False,从小到大排序 print(sorted([22,3,1,4,2,6])) # [1, 2, 3, 4, 6, 22]
# reverse=True,表示从大到小排序 print(sorted([22,3,1,4,2,6],reverse=True)) # [22, 6, 4, 3, 2, 1]
key指定排序内容:
lis = [ {'name':'123','age':22}, {'name':'456','age':18}, {'name':'789','age':19}, ] # 排序,key是指定什么来排序,x相当于lis的每个元素 print(sorted(lis,key=lambda x:x['age'],reverse=True)) # [{'name': '123', 'age': 22}, {'name': '789', 'age': 19}, {'name': '456', 'age': 18}]
18.filter() # 筛选
格式: filter(function, iterable) >>> return filter object
例:
# x为列表中的元素,如果该元素小于10筛选出来 print(list(filter(lambda x:x<10, [22,3,1,4,2,6]))) # [3, 1, 4, 2, 6]
19.map() # 映射
格式: map(function, iterable) >>> return map object
例:
# x为列表中的每个元素,每个元素加10 print(list(map(lambda x:x+10, [i for i in range(1,11)]))) # [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
20.reduce # 累计,可以用来操作列表中的值
使用前需要先导入模块:
form functools import reduce
例:
# 第一次循环,x 为第一个值,y为第二值 # 第二次循环,x 为第一个和第二个值的和, y 为第三个值 print(reduce(lambda x,y:print(x,y), [i for i in range(1,101)])) """ 1 2 None 3 None 4 """
例2: 用ruduce实现一行代码计算1-100的和
print(reduce(lambda x,y:x+y, [i for i in range(1,101)])) # 5050