python 闭包与装饰器

闭包

闭包条件
1.必须要有内函数
2.内函数必须引用外函数变量
3.外函数必须返回内函数

def outer():
    a=10
    print(a)
    def inner():
        print("inner")
    return inner
c=outer()
print(dir(c))
print(c.__closure__) #None

def outer(c):
    a = 300
    def inner():
        print(c + a)
    return  inner
d=outer(10)
d()

print(dir(d))
print(dir(outer))
print(outer.__closure__,d.__closure__) 
#(<cell at 0x0000015E8D41FFD0: int object at 0x0000015E8D2AC270>, <cell at 0x0000015E8D41FFA0: int object at 0x0000015E8CC96A50>)

闭包注意事项

def outer():
    tmp_list=[]
    def inner(name):
        tmp_list.append(name)
        print(tmp_list)
    return inner
d1=outer() #新对象
d1("d1")
d1("d1")
d2=outer() #新对象
d2("d2")
d2("d2")
print(id(d1),id(d2))
print(id(outer(),id(outer()))) #匿名变量 同类型匿名变量的内存地址一般相同

执行时查看变量
在示例中的列表中存放的是inner函数,在调用时查看inner外函数提供的i变量的值,i变量本身应该是要释放的但是由于闭包,被内函数inner所调用,并且inner在f1()f2()f3()才被调用。

def outer():
    fs=[]
    for i in range(5): <---
        def inner():      |
            return i*i ----
        fs.append(inner)
    return fs
f1,f2,f3,f4,f5=outer()
print(f1()) #16
print(f2()) #16
print(f3()) #16

装饰器

装饰器:在不改变源代码的基础上,添加额外功能,本质是闭包
需要传入一个callable对象

# 计算函数执行时间
import time

def func1():
    print("fun1")
    time.sleep(2)

time1=time.time()
func1()
time2=time.time()
print("执行:",time2-time1,"s")

def func2():
    print("func2")

def cost(function):
    start=time.time()
    function()
    end=time.time()
    print(f"执行{function.__name__}时间:{end-start}s")

cost(func1)
cost(func2)

装饰器执行时调用方式没有改变(源码没有改变),将被装饰的函数作为参数传递给装饰器,实际执行的是装饰器的内函数,将需要添加的功能写在内函数中。

# 利用装饰器计算执行时间
import time
def cost(f):
    def _cost():
        start=time.time()
        f()
        end=time.time()
        print(f"执行{f.__name__}时间:{end-start}s")
    return _cost

@cost # func1=runtime(func1)
    # func1=cost(func1)
def func1():
    print("fun1")
    time.sleep(2)

@cost
def func2():
    print("func2")
    time.sleep(2)

func1()
func2()

装饰器的参数

装饰器的应用

用类实现装饰器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值