Python装饰器

10.31 Python装饰器

需要了解装饰器,需要先了解闭包,装饰器中有用到闭包
装饰器就是在不修改函数代码的前提下修改添加函数功能
闭包和装饰器在开发和面试中必问的,常用的

1.闭包

闭包就是多层函数嵌套定义,往往内部函数用到外部函数的变量,把这个整体当作一个特殊的对象
如果在一个内部函数里对外部作用域(但不是全局作用域)的变量进行引用,内部函数称为闭包(closure)

1.1闭包引用

call()方法 创建的实例对象,对对象()执行这个方法
函数里再定义函数返回函数
因为python里都是对象,都是引用
面向对象好处,类之间相互隔离,变量方法分开空间存放,安全。包就和闭包一样
函数:能把代码封装
匿名函数:能完成小部分编写,传实参
闭包:只传一部分数据,拥有函数的功能,还能传一部分数据
类:传过去什么都有

def line(k,b)
    def create_y(x)
        print(k*x+b)
    return create_y #不能加括号,因为返回的是引用函数,而不是函数里的值
line_1 = line(1, 2)
line_1(1)

作为补充:什么是匿名函数:

所谓匿名就是不需要函数表达式	
lambda x : x*x	
关键字lambda表示匿名函数,冒号前面的x表示函数参数。
匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。

1.2闭包修改外部函数变量

类似修改全局变量的global,闭包外边的变量加上nonlocal

2.装饰器

装饰器是程序开发的基础知识,做python开发必须要会
函数是一个引用;
开放封闭原则:
对已实现的功能代码块封闭!
对扩展开放!;
这里就用到装饰器了

定义一个闭包,@闭包名,就是装饰器
如果调用装饰器修饰函数,会先加载对应装饰器;
所以说是可以做到在不修改函数代码的前提下,修改函数的功能;

def set_func(func):
    def call_func():
        print('权限验证1')
        print('权限验证2')
        func()
    return call_func()

@set_func
def test1():
    pass

test1()

2.1装饰器的实现过程:

加装饰器调用test1()相当于
不加装饰器:
test1 = set_func(test)
test1()
会先验证闭包

test1指向内部函数
@这个符号我们就称为语法糖?

23中程序设计模式,其中就有装饰器模式

2.2对有参数函数和无参数函数的修饰

2.2.1 无返回值无参数的最简单
无返回值有参数:

def set_func(func):
    def call_func(num):
        print('权限验证1')
        print('权限验证2')
        func(num)
    return call_func()

@set_func
def test1(num):
    pass

test1(100)

如果有参数,那么闭包里的内部函数也要有形参,内部函数里面的函数调用也要有形参

注意:
同一个装饰器可以对多个函数装饰器,每装饰一个就创建一个闭包。只要写了语法糖?,没有调用函数之前就调用闭包,调用装饰器了

2.2.2 不定长参数函数的装饰
同样的,内部函数形参都换成不定长参数args,**kwargs,内部的引用函数也加上args,**kwargs

def set_func(func):
    def call_func(*args,**kwargs):
        print('权限验证1')
        print('权限验证2')
        func(*args,**kwargs)
    return call_func()

@set_func
def test1(num,*args,**kwargs):
    pass

test1(100,200,300,mm=100)

2.2.3 有参数,有返回值

def set_func(func):
    def call_func(*args,**kwargs):
        print('权限验证1')
        print('权限验证2')
        return func(*args,**kwargs)
    return call_func()

@set_func
def test1(num,*args,**kwargs):
    return 'ok'

ret = test1(100,200,300,mm=100)
print(ret)

这个就是通用装饰器,就算没有返回值也不会报错,因为没有返回值会返回None

2.2.4 多个装饰器对同一个函数装饰
多个装饰器可以对同一个函数装饰,就是经过装饰器的层层过滤;
如果多个装饰了,先装饰离被装饰函数近的,就是下面的再装饰上面的,执行反过来,先执行上面的再执行下面的
demo:


def set_fun_1(func):
    def call_func():
        return '<h1>'+func()+'</h1>'
    return call_func

def set_fun_2(func):
    def call_func():
        return '<tb>'+func()+'</tb>'
    return call_func

@set_fun_1
@set_fun_2
def get_str():
    return 'haha'

print(get_str())

>>>>>> <h1><tb>haha</tb></h1>

2.2.5带参数的装饰器
定义三个函数嵌套,因为原来最外层的函数参数已经接收了被装饰函数的函数名,所以在外面再定义一个函数,这样完成了带参数的装饰器

2.2.6 类装饰器
类装饰器可以装饰函数也可以装饰类
这个用的很少,不写了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值