导读:装饰器——在不更改原函数的代码的前提下给函数增加新的功能,特殊之处在于它的返回值也是一个函数。话不多说,上代码体验!
闭包示例代码
def fun1(name1): def fun2(name2): # 4.hello传到这儿了,函数这东西不调用就不执行 print(name1 + name2) print('2') # 1.上面函数没调用就不执行,直接从这儿开始 return fun2 # 2写的是函数名,返回地址 a = fun1('tom') a('hello') # 3指向fun1的返回值即fun2('hello') a('hi') # 5同上
通过闭包更改外部函数值用nonlocal arg
def func_out(num1): def func_inner(num2): nonlocal num1 # 可以改变这个值 num1 = num1 + num2 print("num1:", num1) print(num1) func_inner(1) # 之所以这样,因为得跑一遍才能改呀,直接打印num1,数据流没跑到那儿肯定没修改。 print(num1) return func_inner f = func_out(1) f(2)
装饰器基础结构
def check(fn): def inner(): print("请先登录....") fn() # 5指向comment() return inner # 1指向下面的调用者comment def comment(): print("发表评论") # 6 comment = check(comment) # 2 comment装的是inner函数的地址。可改成@check即装饰器,放在被装饰方法comment()的上方。 comment() # 3指向inner()
装饰器案例-时间统计
import time def outer(func): def inner(): star_time = time.time() func() end_time = time.time() print('花费时间:%f' % (end_time - star_time)) return inner @outer def func(): for i in range(9): print(i) func()
通用装饰器
(包含了不定长参数、带返回值函数;多debug,先执行两个装饰器,跑没头了,给调用它的人)
def logging(fn): def inner(*args, **kwargs): print("--正在努力计算--") result = fn(*args, **kwargs) # 藏的有点深啊,所以下面不必再写sum_num()这个指向inner的方法。 return result return inner @logging def sum_num(*args, **kwargs): result = 0 for value in args: result += value print(result) for value in kwargs.values(): result += value print(result) return result @logging def subtraction(a, b): result = a - b print(result) result = sum_num(1, 2, a=10) print(result) subtraction(4, 2)
类装饰器
class Check(object): def __init__(self, fn): # 初始化操作在此完成 self.__fn = fn # 实现__call__方法,表示对象是一个可调用对象,可以像调用函数一样进行调用。 def __call__(self, *args, **kwargs): # 添加装饰功能 print("请先登陆...") self.__fn('sdf') @Check def comment(): print("发表评论") comment() check=Check(print) #也可以改input,拓展:上面args[0]('注册')表示print('注册'),间接表明一切皆对象。 check()
多装饰器
def make_div(func): """对被装饰的函数的返回值 div标签""" def inner(*args, **kwargs): return "<div>" + func() + "</div>" return inner def make_p(func): """对被装饰的函数的返回值 p标签""" def inner(*args, **kwargs): return "<p>" + func() + "</p>" return inner # 装饰过程: 1 content = make_p(content) 2 content = make_div(content) # content = make_div(make_p(content)) @make_div @make_p def content(): return "你好哈哈" result = content() print(result)