趣百科

Python-闭包函数如何实现装饰器

编辑:Simone 2025-03-24 01:16:25 522 阅读

Python-闭包函数如何实现装饰器

根据闭包函数的特性,来对另一个函数进行装饰,或者添加,或者限定某些功能。

(详细的闭包函数看下面的链接。)

关键知识:

1)了解函数的作用域;

2)函数名是内存的地址,加了圆括()才算是调用。

3)闭包函数的过程:a.函数嵌套;b.内函数使用外函数嵌套域的变量;c.外函数返回内函数的函数名;d.在全局域引用外部函数(即得到内部函数的函数名)并加圆括号。

def outFun(): a='嵌套域a' def inFun(): b='本地域引用:'+a return b return inFuninFun=outFun()print(inFun())

注意:在调用outFun()函数时,赋值的名字是自由的,可以是a=outFun(),也可是outFun=outFun()。但加了括号后的结果都是一样的。

0Python-如何实现闭包函数

传参数:

def outFun(a): def inFun(b): b=b+a return b return inFuninFun=outFun('嵌套域a')print(inFun('本地域引用:'))

同样是内部函数引用了外部函数的变量a。

可以用函数的特殊属性inFun.__closure__来验证是否引用了嵌套域的变量。

用inFun.__closure__.cell_contents查值。

(上面的验证方法不用做多的解读,了解即可)

既然传参是可行的,那么可做的文章就大了,装饰器就是使用闭包函数,使得代码在复用上更上一层楼。

通俗讲装饰器就是在调用原函数时,能给原函数添加额外的功能,而原函数并不发生改变。

第一步:定出装饰的样子。

例如:

def orignalFun(): print('我自横刀向天笑\n' '去留肝胆两昆仑'def outFun(): print('='*13) orignalFun() print('='*13)outFun()

=============

我自横刀向天笑

去留肝胆两昆仑

=============

这样在一个函数内嵌套原始函数,就实现了一个简单的装饰。

第二部:

1)因为上一步的装饰线只能给一个函数装饰,要想给其他函数装饰,必须得再写一遍。

2)为了复用outFun(),可以将原始函数名字当outFun()的实参传入,在outFun内加圆括号实现调用。

3)这样只需调用outFun(原始参数名字),就能实现对outFun()代码的复用。

例如:

def orignalFun1(): print('我自横刀向天笑\n' '去留肝胆两昆仑')def orignalFun2(): print('把酒酹滔滔,\n' '心潮逐浪高')def outFun(a): print('='*13,) a() print('='*13)outFun(orignalFun1)outFun(orignalFun2)

第三步:

1)然而这依然没有达到要求,上例中调用的时outFun(),而非原函数。这时闭包功能就能实现这个操作。

2)先定义一个闭包函数,实现要装饰代码。此时调用的是内部函数。

def outFun(a): def inFun(): print('='*13) print(a) print('='*13) return inFuninFun=outFun('装饰我把')inFun()

第四步:

按第二步的方法,将需要装饰的原函数的名称当做outFun()的实参传入,并在内部函数内加圆括号调用。

def orignalFun1(): print('我自横刀向天笑\n' '去留肝胆两昆仑'def outFun(a): def inFun(): print('='*13) a() print('='*13) return inFuninFun=outFun(orignalFun1)inFun()

第五步:

在全局域内调用outFun(),并赋值给与原函数名相同的变量。然后加括号调用,即实现了装饰器。

def orignalFun1(): print('我自横刀向天笑\n' '去留肝胆两昆仑'def outFun(a): def inFun(): print('='*13) a() print('='*13) return inFunorignalFun1=outFun(orignalFun1)orignalFun1()

这样,写好了outFun的功能后,要想给一个函数装饰outFun()的功能,只需做第五步就可以了,就能实现不改变原函数的情况下,装饰其他要装饰的函数。

第六步:参数问题的解决。

1)上面的例子原始函数并没有参数,如果有参数,而且多种多样,有时参数数量,类型都不同,就需要通过内部函数传参,原始函数在内部调用这些参数。

2)但是装饰器是写后不修改,拿来就能用的,不可能每次使用都有修改参数。

3)那么就给内部函数,和调用的原始函数都用可变参数*args和关键字参数**kwargs,就可以接收所有类型的实参了。

例如:

def areaT(a,b,h): v=a*b*h print(f'体积:{v}m³')def outFun(a): def inFun(*args,**kwargs): print('='*13) a(*args,**kwargs) print('='*13) return inFunareaT=outFun(areaT)areaT(2,3,4)

第七步:

然而这还不是最简便,python给了更简便的方法。

1)在要装饰的函数的上一行,加上@装饰函数,无需在调用outFun()函数。

2)这时调用原函数,就实现了装饰的效果。

def outFun(a): def inFun(*args,**kwargs): print('='*13) a(*args,**kwargs) print('='*13) return inFu@outFundef areaT(a,b,h): v=a*b*h print(f'体积:{v}m³'areaT(20,10,3)

版权声明:本站【趣百科】文章素材来源于网络或者用户投稿,未经许可不得用于商用,如转载保留本文链接:https://www.qubaik.com/answer/162592.html

相关推荐