装饰器
定义
装饰器是一个函数,主要用来包装另一个函数或类,加载模块时装饰器已经执行。
装饰器本质上就是一个闭包函数,它可以对已有函数进行额外的功能扩展。
闭包函数有且只有一个参数,必须是函数类型,这样定义的函数才是装饰器。
作用
装饰的目的通常是在不改变原函数名(或类名)的情况下,改变或添加原函数的功能
语法
@装饰器函数名 等价于 函数名 = 装饰器函数名(函数名)
装饰器的执行时间是加载模块时立即执行。
def 装饰器函数名( 参数) :
语句块
return 函数对象
@装饰器函数名
def 函数名( 形参列表) :
语句块
1.有参数无返回值
def func ( fun) :
def inner ( num) :
print ( "--这是权限验证---" )
fun( num)
return inner
@func
def test ( num) :
print ( "---这是被装饰函数---" )
print ( "num is %d" % num)
test( 100 )
2.不定长传参
def func ( fun) :
def inner ( * args, ** kwargs) :
print ( "--这是权限验证---" )
fun( * args, ** kwargs)
return inner
@func
def test ( * args, ** kwargs) :
print ( "---这是被装饰函数---" )
print ( "*args is " , args)
print ( "**kwargs is " , kwargs)
test( 100 , num= 200 )
3.带返回值
def func ( fun) :
def inner ( * args, ** kwargs) :
print ( "--这是权限验证---" )
return fun( * args, ** kwargs)
return inner
@func
def test ( num, * args, ** kwargs) :
print ( "---这是被装饰函数---" )
return "ok"
print ( test( 100 ) )
4.多个装饰器对同一个函数装饰
注:
1.多个装饰器的装饰过程是: 离函数最近的装饰器先装饰,然后外面的装饰器再进行装饰,
由内到外的装饰过程
2.调用函数时则先执行外部的make_div装饰器 再执行make_p
def make_div ( func) :
"""对被装饰的函数的返回值 div标签"""
def inner ( * args, ** kwargs) :
return "<div>" + func( ) + "</div>"
return inner
def make_p ( func) :
"""对被装饰的函数的返回值 p标签"""
def inner ( * args, ** kwargs) :
return "<p>" + func( ) + "</p>"
return inner
@make_div
@make_p
def content ( ) :
return "人生苦短"
result = content( )
print ( result)
5.带有参数的装饰器
注:
1.装饰器只能有一个参数且是函数名 set_func是装饰器
2.带有参数的装饰器,其实就是定义了一个函数,让函数接收参数,
在函数内部返回的是一个装饰器
def set_level ( level_num) :
def set_func ( func) :
def call_func ( * args, ** kwargs) :
if level_num == 1 :
print ( "--权限验证1--" )
else :
print ( "--权限验证2--" )
return func( )
return call_func
return set_func
@set_level( 1 )
def test1 ( ) :
print ( "--test1--" )
test1( )
6.类装饰器
注:
__call__相当于将类的实例对象能直接像函数一样使用
例如:
a = Test()
a() #这是装饰器添加的功能
class Test ( object ) :
def __init__ ( self, func) :
self. func = func
def __call__ ( self) :
print ( "这是装饰器添加的功能" )
return self. func( )
@Test
def get_str ( ) :
return "haha"
print ( get_str( ) )
7.带参数的类装饰器
class AAA ( object ) :
def __init__ ( self, flag) :
self. __flag = flag
def __call__ ( self, func) :
def inner ( * args, ** kwargs) :
if self. __flag == "+" :
print ( "加法" )
print ( "课已讲完" )
func( * args, ** kwargs)
return inner
@AAA( "+" )
def show11 ( ) :
print ( "快要下课啦" )
show11( )
8.functools.wraps的用法
import functools
def log ( func) :
@functools. wraps( func)
def wrapper ( * args, ** kwargs) :
print ( "这个函数是 %s" % func. __name__)
return func( * args, ** kwargs)
return wrapper
@log
def now ( ) :
print ( "hello" )
return 1
print ( now( ) )
print ( now. __name__)
9.在类中使用装饰器
class Buy ( object ) :
def __init__ ( self) :
self. reset = True
self. func = True
def clothes ( func) :
def ware ( self, * args, ** kwargs) :
print ( 'This is a decrator!' )
if self. reset == True :
print ( 'Reset is Ture, change Func..' )
self. func = False
else :
print ( 'reset is False.' )
return func( self, * args, ** kwargs)
return ware
@clothes
def body ( self) :
print ( 'The body feels could!' )
b = Buy( )
b. body( )
print ( b. func)