闭包,装饰器

1 闭包

是么是闭包;定义在函数内部函数,引用了外部函数作用域的名字

闭包也可以是传参的一种方式

原来学过函数是通过形参,实参传递参数,现在又多了一种方式,闭包

比如;

def func(x):
    
    def index():
        print(x)
    return index

ret = func(12)
ret()

 2 装饰器

什么是装饰器;,装饰器就是一个可以给被装饰对象添加新功能的工具

装饰器的开放封闭原则;

  对扩展开放

  对修改关闭

装饰器必须准守的两个原则

  不修改被装饰对象原代码

  不修改被装饰对象的调用方式

 

我们先来定义一个函数

# 我们先来定义一个函数,在将这个函数扩展一些功能
# 我想要这个函数在具备一些特定的功能,比如我要知道这个函数运行了多少时间
# 那我们可以这么写
import time

def func():

    time.sleep(3)
    print("func")


start_time = time.time()
func()
end_time = time.time()
print("运行了%s"%(end_time-start_time))

 

但这样,如果是用户,他只会去调用这个函数,虽然没有改变函数源代码,也没有改变调用方式

但总感觉,不是太理想

 

 

那我们可以这样,将下面调用函数周围的代码封装到一个函数

import time

def index():
    time.sleep(2)
    print("func")

def outer(func):

    def inner():
        start_time = time.time()
        func()
        end_time = time.time()
        print("运行了%s"%(end_time-start_time))
    return inner

index = outer(index)
index()

 

 那如果说我们要修改的函数需要参数,那这种就不会满足了,就出现了下面这种情况

import time

def index(x):
    time.sleep(2)
    print(x)

def outer(func):

    def inner(*args,**kwargs):
        start_time = time.time()
        func(*args,**kwargs)
        end_time = time.time()
        print("运行了%s"%(end_time-start_time))
    return inner

index = outer(index)
index(1)

 

 

但是除了这几种情况,我们还遇到了有返回值的函数,所以现在的装饰器还是不完美,我们还需要修改,做到以假乱真

import time

def index(x):
    time.sleep(2)
    print(x)
    return x

def outer(func):

    def inner(*args,**kwargs):
        start_time = time.time()
        ret = func(*args,**kwargs)
        end_time = time.time()
        print("运行了%s"%(end_time-start_time))
        return ret

    return inner

index = outer(index)
set = index(1)
print(set)

 

 

 

当装饰器,写完了过后,我们就要学习装饰器的语法糖

格式;

@函数名(函数可以这么理解;就是装饰器外围函数)

注意一点,装饰器语法糖它是装饰与自己紧挨这的那个函数名

书写语法,必须与函数紧挨着,不能有空格

 

 

如果接的装饰器不太好理解,我们也有办法,那就是装饰器模板

def outer(func):
    def inner(*args,**kwargs):
        print("执行被装饰的对象被调用之前的功能")
        ret = func(*args,**kwargs)
        print("执行被装饰的对象被调用之后的功能")
        return ret
    return inner

 

 

 装饰器传值

def outer1(a,b,c):
    def outer(func):
        def inner(*args,**kwargs):
            print("你好帅")
            print(a,b,c)
            ret = func(*args,**kwargs)
            print("可以借点钱不")
            return ret
        return inner
    return outer

@outer1(1,2,3)
#outer1(123) 返回的是outer 那么下一步就继续@outer  等价以index = outer(index)
 
def index(x): print("*"*10+"hello world"+"*"*10) return x ret = index(1) print(ret)

 

 

 

outer1(123) 返回的就是 outer

所以就继续下一步@outer装饰器的功能、

 

装饰修复技术

可以将装饰器的函数的地址,返回值都改为被装饰类型的地址

from functools import wraps


def outer(func):
    @wraps(func)
    def inner(*args,**kwargs):
        print("$$$$$$$$$$$$$$$$$$$$$$")
        ret = func(*args,**kwargs)
        print("$$$$$$$$$$$$$$$$$$$$$$$")
        return ret
    return  inner

@outer
def index():
    print("index")
    return 111

ret = index()
print(ret)
print(help(index))

 

 

 多层装饰器

def outer1(func):
    print("outer1")
    def inner1(*args,**kwargs):
        print("inner1")
        ret = func(*args,**kwargs)
        return ret
    return inner1

def outer2(func):
    print("outer2")
    def inner2(*args,**kwargs):
        print("inner2")
        ret = func(*args,**kwargs)
        return ret
    return inner2

def outer3(func):
    print("outer3")
    def inner3(*args,**kwargs):
        print("inner3")
        ret = func(*args,**kwargs)
        return ret
    return inner3

@outer1         #index = outer1(inner2)
@outer2         #inner2 = outer2(inner1)
@outer3         #inner = outer3(index)
def index():
    print("index")

index()

 

转载于:https://www.cnblogs.com/cherish937426/p/11171832.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值