当你处于低潮期的时候,好好想想,就算现在攒不到钱,攒点知识,交情,经验,最不济攒点教训也行!
装饰器一定要多加练习,装饰器是越练越熟练;后面很多框架一装饰就能用了,
经常见到的各种类型的装饰器都要练一遍;
本章总结:
- 无参、有参、缓存装饰器、通用装饰器、 1.40;
- 装饰器是AOP面向对象编程 Aspect Oriented Programming思想的体现;
- 想装饰器 return 是什么 很重要,
装饰器
装饰器(Decorator)是python的一个重要部分,简单来说,他是修改其他函数功能的函数。
它是一种不修改原来的业务代码,给程序动态添加功能的技术;例如logger函数功能就是对业务函数增加日志的,而业务函数中应该吧业务无关的日志玻璃干净;
他们有助于让我们的代码更简短,也更Pythonic!
解除装饰器:
可以访问 _wrapped_属性来访问原始函数
orig_add = add.__wrapped__
orig_add(1,2)
装饰器应用场景
日志、监控、权限、设计、参数检查、路由等处理
这些功能与业务功能无关,很多业务都需要的公有的功能,所以适合独立出来,对目标对象进行增强;
1. 缓存装饰器实现;
from functools import wraps
import inspect,datetime
def mag_cache(fn):
local_cache = {}
@wraps(fn)
def wrapper(*args, **kwargs):
# 参数处理,构建key
sig = inspect.signature(fn)
params = sig.parameters
params_dict = {}
values = list(params.values())
keys = list(params.keys())
# 位置和关键字传参
params_dict.update(zip(params.keys(),args))
params_dict.update(kwargs)
# 缺省值
for k,v in params.items():
if k not in params_dict:
params_dict[k] = v.default
key = tuple(sorted(params_dict.items()))
print(key)
if key not in local_cache.keys():
local_cache[key] = fn(*args,**kwargs)
return local_cache[key]
return wrapper
@mag_cache
def add(x,y,z=6):
datetime.sleep(2)
return x+y+z
2.命令分发器实现
# 1 基本框架
# 第一个版本:
commands = {}
def reg(cmd, fn):
commands[cmd] = fn
def defaultfn():
print("Unknown command")
def foo1(): # 硬编码
print('magedu')
def foo2(): # 硬编码
print('python')
reg('mag', foo1)
reg('py', foo2)
def dispatcher():
while True:
cmd = input('>>>').strip()
if cmd == '':
print('bye')
return
commands.get(cmd, defaultfn)()
dispatcher()
-------------------------------------
>>>mag
magedu
>>>py
python
>>>
bye
# 2 柯里化变有参
commands = {}
def reg(cmd):
def _reg(fn):
commands[cmd] = fn
return fn
return _reg
def defaultfn():
print("Unknown command")
@reg('mag')
def foo1():
print('magedu')
@reg('py')
def foo2():
print('python')
#reg('mag', foo1)
#reg('py', foo2)
def dispatcher():
while True:
cmd = input('>>>').strip()
if cmd == '':
print('bye')
return
commands.get(cmd, defaultfn)()
dispatcher()
-------------------------------------
>>>mag
magedu
>>>py
python
>>>
bye
# 3 函数封装
def cmds_dispatcher(defaultfn=lambda :print('Unknown command')):
commands = {}
def reg(cmd):
def _reg(fn):
commands[cmd] = fn
return fn
return _reg
#def defaultfn():
# print("Unknown command")
def dispatcher():
while True:
cmd = input('>>>').strip()
if cmd == '':
print('bye')
return
commands.get(cmd, defaultfn)()
return reg,dispatcher
reg, dispatcher = cmds_dispatcher()
@reg('mag')
def foo1():
print('magedu')
@reg('py')
def foo2():
print('python')
#reg('mag', foo1)
#reg('py', foo2)
dispatcher()
网友评论