热门IT资讯网

由浅入深,走进Python装饰器-----第一篇:基础,原型

发表于:2024-11-23 作者:热门IT资讯网编辑
编辑最后更新 2024年11月23日,摘要: 本文从学习装饰器需要用到的基础知识入手, 用简单代码附以实例验证,在彻底理解基础知识的情况下帮助逐步理解, 装饰器的原型要点: 从闭包及函数名可当参数传递作为基础理解思路, 由浅入深引入Pyt

摘要: 本文从学习装饰器需要用到的基础知识入手, 用简单代码附以实例验证,在彻底理解基础知识的情况下帮助逐步理解, 装饰器的原型

要点: 从闭包及函数名可当参数传递作为基础理解思路, 由浅入深引入Python装饰器原型, 进而引出装饰器



**装饰器背景:**   在不改变原函数代码,  且保持原函数调用方法不变的情况下,  给原函数增加新的功能 (或者给类增加新属性和方法)


**核心思想: **      用一个函数(或者类) 去装修 一个旧函数 (或者类)   , 造出一个新函数(或者新类)

Python万物皆对象, 可以随意赋值使用

def func():    print("第三: ","我是一个函数的输出结果")a = 1print("第一: 我是一个变量 ",a)a = func                                                        #将函数名赋值给变量print("第二: 我是一个函数名 ",a)a()>>>第一: 我是一个变量 1>>>第二: 我是一个函数名 >>>第三: 我是一个函数的输出结果

变量作用域

# 根据 LEGB原则, 内函数使用外函数的局部变量def outer():    a = 0    print("我是外部函数的 a:",a)    def inner():        print("我是内部函数打印的 a:",a)> > > 我是外部函数的 a: 0> > > 我是内部函数打印的 a: 0# 引入 nonlocal, 内函数可以修改外函数def outer():    a = 0    print("我是外部函数的 a:",a)    def inner():        nonlocal a        a += 1        print("我是内部函数加工过的 a:",a)>>>我是外部函数的 a: 0>>>我是内部函数加工过的 a: 1

闭包( 延长局部变量生存时间 )

# 内函数  夹带  外函数的局部变量def outer():    a = 0    print("我是外部函数打印的 a:",a)    def inner():        print("我是内部函数打印的 a:",a)    return innerres = outer()                                        # res接收的是一个函数名print("我是返回出来的内函数名: "res)res()>>>我是外部函数打印的 a: 0>>>我是返回出来的内函数名: >>>我是内部函数打印的 a: 0>>>#  内函数  夹带  修改后的外函数的局部变量def outer():    a = 0    print("我是外部函数打印的 a:",a)    def inner():        nonlocal a        a += 1        print("我是内部函数修改过的 a:",a)    return innerres = outer()                                       # res接收的是一个函数名print("我是返回出来的内函数名: "res)res()>>>我是外部函数打印的 a: 0>>>我是返回出来的内函数名: >>>我是内部函数修改过的 a: 1

函数名可以当做参数传递

#新函数对旧函数修饰def old():    print('我是 旧函数')     def new(f):    print('我是 新函数, 我可以输出 旧函数')    f() new( old )                        #把旧函数名当做参数, 传递给新函数, 在新函数内产生变化>>>我是 新函数, 我可以输出 旧函数>>>我是 旧函数

装饰器原型

# ### 利用闭包,将函数名当参数传递def outer(f):    def inner():        print("我是外部传进来的old :",f)        f()        print("我是修饰工,我在旧函数后显示")    return innerdef old():    print("我是旧函数")print("我是最初的old: ",old)                         print("我是返回出来的内函数inner: ",outer(old))   #outer把函数名old当参数传回函数内部进行加工, 把函数名inner返回old = outer(old)                            #实际上, 旧函数名old已被重新赋值为innerprint("我不是原来的old了 ",old)old()                                       #经过改造, 虽然调用结果不变, 但是运行结果已变化>>>我是最初的old:               >>>我是返回出来内函数inner:     .inner at 0x00000000021CAAE8>>>>我不是原来的old了            .inner at 0x00000000021CAAE8>>>>我是外部传进来的old :        >>>我是旧函数>>>我是修饰工,我在旧函数后显示

装饰器

# ### 用 @outer 修饰def outer(f):    def inner():        print("我是外部传进来的old :",f)        f()        print("我是修饰工,我在旧函数后显示")    return inner@outer                       #实际上,将  old = outer(old)  这句改成 @outer, 放在old函数上方def old():    print("我是旧函数")old()                                                                 >>>我是外部传进来的old : >>>我是旧函数>>>我是修饰工,我在旧函数后显示

装饰器的嵌套: 下层装饰器修饰后的函数, 再次被上层装饰器修饰

def kuozhan(f):    def inner():        print("1我是扩展函数,接收外部传进来的新old :",f)        f()        print("4我是扩展函数,我在新old函数后显示")    return innerdef outer(f):    def inner():        print("2我是outer函数,接收外部传进来的old :",f)        f()        print("3我是outer函数,我在old函数后显示")    return inner@kuozhan               #old = kuozhan(outer(old))@outer                 #old = outer(old)def old():    print("我是old函数")old()>>>1 我是扩展函数,接收外部传进来的新old : .inner at 0x000000000250AB70>>>>2 我是外部传进来的old :               >>>  我是old函数>>>3 我是修饰工,我在旧函数后显示>>>4 我是扩展函数,我在新old函数后显示
0