【python】闭包和装饰器

闭包

嵌套函数内,使用非全局非当前空间的变量(自由变量)的就是闭包

代码:

def a():
    num = 123
    def b():
        print(num)
    return b
a()()

def c(num):
    def d():
        print(num)
    return d
c(123)()

结果:

123
123

验证是否为闭包

代码:

def a(num):
    def b():
        print(num)
    return b
avg = a(123)
print(avg.__code__.co_freevars) # 查看函数的自由变量

结果:

('num',)

闭包的作用
保存局部信息不被销毁,保证数据的安全性。
闭包的应用

  1. 可以保存一些非全局变量但是不易被销毁、改变的数据。
  2. 装饰器

装饰器

开放封闭原则

  1. 对扩展是开放的
  2. 对修改是封闭的

什么是装饰器

在不改变原被装饰的函数的源代码以及调用方式下,为其添加额外的功能。

代码:

def a(fun):
    def al(*args, **kwargs):
        # 装饰前
        print("这是装饰前")
        num = fun(*args, **kwargs)
        # 装饰后
        print("这是装饰后")
        return num
    return al
@a # 语法糖
def b(*args, **kwargs):
    print(*args, **kwargs)
b(123)

结果:

这是装饰前
123
这是装饰后

对语法糖进行拆解

代码:

def a(fun):
    def al(*args, **kwargs):
        # 装饰前
        print("这是装饰前")
        num = fun(*args, **kwargs)
        # 装饰后
        print("这是装饰后")
        return num
    return al
# @a # 语法糖
# def b(*args, **kwargs):
# 	print(*args, **kwargs)
#b(123)

def b(*args, **kwargs):
	print(*args, **kwargs)
b = a(b)
b(123)

结果:

这是装饰前
123
这是装饰后

有参装饰器

代码:

def al(num): # 参数
    def a2(b1):
        def a3(*args,**kwargs):
            if num: # 判断传入的参数
                return b1(*args,**kwargs)
            else:
            	print("Flase")
        return a3
    return a2
@al(1) # 传参
def bl(*args,**kwargs):
    return "bl"
print(bl()) 

结果:

bl

多个装饰器装饰一个函数

优先执行最近的装饰器

代码:

def a1(fun):
    def a2():
        print("a1装饰器前") # 第二步
        fun() # 第五步
        print("a1装饰器后") # 第七步
    return a2
def b1(fun):
    def b2():
        print("b1装饰器前") # 第三步
        fun() # 第四步
        print("b1装饰器后") # 第六步
    return b2
@a1
@b1
def c():
    print("函数c") # 第五步
c() # 第一步

结果:

a1装饰器前
b1装饰器前
函数c
b1装饰器后
a1装饰器后

functools.wrap

使用functools.wrap后会保留函数的元数据(函数名/注释)

代码:

import functools


def wrapper(func):
    @functools.wraps(func)
    def wrapper():
        print 'before'
        func()
        print 'after'
    return wrapper

@wrapper
def foo():
    print 'foo'
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值