装饰器和匿名函数:
例一:实现计数功能:
def defunc(func): print('-------------------hello') count = 0 def mapper(*args,**kwargs): nonlocal count print('欢迎调用{}函数第{}次'.format(func.__name__,count)) func(*args,**kwargs) count+=1 return mapper @defunc def show(): print('这是显示函数show...') for i in range(3): show() ''' -------------------hello 欢迎调用show函数第0次 这是显示函数show... 欢迎调用show函数第1次 这是显示函数show... 欢迎调用show函数第2次 这是显示函数show... '''
1、*args **kwargs 在函数中的使用
如果想让装饰器函数达到通用性,则需要在内层函数中添加可变参数
这样无论装饰的函数是有参数还是没有参数,或者有关键字参数都可以装饰
2、要装饰的函数有返回值,装饰器的内层函数也要有返回值,从而保证装饰后的函数与原函数保持一致性。
例:使用装饰器进行用户的登录验证:
islogin = False def login_requierd(func): def wrapper(*args, **kwargs): global islogin if islogin: func(*args, **kwargs) else: print('-----------用户没有登录,请登录') f = login() if f: func(*args, **kwargs) return wrapper def login(): global islogin username = input('请输入用户名:') password = input('请输入密码:') if username == 'gang' and password == '123': islogin = True return islogin return islogin @login_requierd def buy_ticket(): ticket = {'中关村店:': ('哪吒', ['11:35 一号厅', '12:15 二号厅', '13:45 三号厅'])} for key, value in ticket.items(): print('影院', key) print('播放的电影是', value[0]) print('播放的时间是:') for i in value[1]: print('--->', i) # login() buy_ticket() ''' -----------用户没有登录,请登录 请输入用户名:gang 请输入密码:123 影院 中关村店: 播放的电影是 哪吒 播放的时间是: ---> 11:35 一号厅 ---> 12:15 二号厅 ---> 13:45 三号厅 '''
3、装饰器参数: 三层函数实现的
def 装饰器名(参数): def second(函数参数): def third(*args,**kwargs): .... .... return third return second
def decorator(number): print('------>1') def decorator1(func): print('------->2') def wrapper(*args, **kwargs): print('-----start') func(*args, **kwargs) print('--------end') print('-------->3') return wrapper print('------->4') return decorator1 @decorator(10) def show(): print('------->调用show函数') show() ''' ------>1 ------->4 ------->2 -------->3 -----start ------->调用show函数 --------end '''
4、多层装饰器:
谁离原函数最近先执行哪个装饰器,将第一层装饰器的返回结果传给第二层装饰器
最后:原函数得到的地址是第二层函数的返回值wrapper
def decorator1(func): def wrapper(*args,**kwargs): func(*args,**kwargs) print('刷地板') print('刷漆') return wrapper def decorator2(func): def wrapper(*args,**kwargs): func(*args,**kwargs) print('买家具') print('买沙发') print('买装饰品') return wrapper @decorator2 @decorator1 def house(): print('----------未装修房子') print(house) house() ''' <function decorator2.<locals>.wrapper at 0x000001A795094510> ----------未装修房子 刷地板 刷漆 买家具 买沙发 买装饰品 '''
5、匿名函数:
定义格式: lambda 参数:返回值
使用:1、函数体非常简单 2、使用次数较少
f = lambda n:n+1 print(f) r = f(5) print(r) f1 = lambda x,y:x+y r = f1(1,2) print(r)
例子:
list1 = [('tom',12),('lucy',20),('lily',16),('luze',19),('jerry',34)] list2 = sorted(list1,key=lambda x:x[1],reverse=True) print(list2) #[('jerry', 34), ('lucy', 20), ('luze', 19), ('lily', 16), ('tom', 12)]
6、高阶函数:把函数当成参数进行传递的函数
1》sorted(iterable,key,reverse) 其中key就是一个函数参数
dict1 = {'tom':12,'lucy':20,'lily':16,'luze':19,'jerry':34} result = sorted(dict1.items(),key=lambda x:x[1]) dict1 = dict(result) print(dict1) #{'tom': 12, 'lily': 16, 'luze': 19, 'lucy': 20, 'jerry': 34}
2》map映射 map(function,iterable)
给一个可以迭代的对象,通过function的作用,将其转成一个新的对象
map1 = map(lambda x: x ** 2, [1, 2, 3, 4, 5]) print(map1) print(list(map1)) # <map object at 0x0000023D21830C18> # [1, 4, 9, 16, 25] names = ['tom', 'java', 'c#', 'python'] map2 = map(lambda x: x.capitalize(), names) print(list(map2)) # ['Tom', 'Java', 'C#', 'Python'] map0 = map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6]) print(list(map0)) # [5, 7, 9]
3》filter(function,iterable):返回值是一个filter
需要对返回值进行转换:list(filter_object)
function函数的返回值必须是bool类型
num = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 13, 24] filter1 = filter(lambda x: x % 2 == 0, num) print(list(filter1)) # [2, 4, 6, 8, 0, 10, 24]
list1 = ['hello', 67, 'nihao', '99', '25', 'gang'] filter1 = filter(lambda x: str(x).isdigit(), list1) print(list(filter1)) # [67, '99', '25'] filter2 = filter(lambda x: isinstance(x, int) or x.isdigit(), list1) print(list(filter2)) # [67, '99', '25']
4》reduce(function,iterable)
参数function是函数,此函数的参数必须两个 lambda x,y:x*y
参数iterable是一个可迭代对象
from functools import reduce list1 = [1, 2, 3, 5] result = reduce(lambda x, y: x + y, list1, 2) print(result) # 13 result = reduce(lambda x, y: x + y, range(1, 7)) print(result) # 21
7、functools模块
partial() 偏函数 是通过将一个函数的部分参数预先绑定为某些值,从而得到一个新的具有较少可变参数的函数。
from functools import partial,wraps int1 = partial(int,base=8) print(int1('123')) # 83
wraps() 消除装饰器带来的一些副作用
获取对象名: house.__name__ 获取函数名 house.__doc__ 获取文档注释
python装饰器:在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变)为了不影响,python的functools包中提供了一个叫wraps的decorator来消除这样的副作用。
from functools import partial, wraps def decorator1(func): @wraps(func) def wrapper(*args,**kwargs): func(*args,**kwargs) print('铺地板') print('刷漆') return wrapper def house(): print('----------未装修房子') print(house.__name__) print(house.__doc__) house() # house # None # ----------未装修房子
8、列表推导式:
格式:[表达式 for i in list|set|tuple|dict [if 条件]]
格式:[表达式1 if 条件 else 表达式2 for i in list|set|tuple|dict [if 条件]]
格式:[表达式 for i in list|set|tuple|dict for i in list|set|tuple|dict ]
list1 = [1,3,5,2,5,7] list2 = [x for x in list1 if x%2==0] print(list2) #[2] list3 = [x+1 if x%2==0 else x+2 for x in list1] print(list3) # [3, 5, 7, 3, 7, 9] list0 = [1,2,3] list4 = [2,4,6] list5 = [(x,y) for x in list0 for y in list4] print(list5) # [(1, 2), (1, 4), (1, 6), (2, 2), (2, 4), (2, 6), (3, 2), (3, 4), (3, 6)]