日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python常用的装饰器库_Python中的各种装饰器详解

發(fā)布時間:2025/3/15 python 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python常用的装饰器库_Python中的各种装饰器详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Python裝飾器,分兩部分,一是裝飾器本身的定義,一是被裝飾器對象的定義。

一、函數(shù)式裝飾器:裝飾器本身是一個函數(shù)。

1.裝飾函數(shù):被裝飾對象是一個函數(shù)

[1]裝飾器無參數(shù):

a.被裝飾對象無參數(shù):

>>> def test(func):

def _test():

print 'Call the function %s().'%func.func_name

return func()

return _test

>>> @test def say():return 'hello world'

>>> say() Call the function say(). 'hello world' >>>

b.被裝飾對象有參數(shù):

>>> def test(func):

def _test(*args,**kw):

print 'Call the function %s().'%func.func_name

return func(*args,**kw)

return _test

>>> @test def left(Str,Len): ??? #The parameters of _test can be '(Str,Len)' in this case. ??? return Str[:Len]

>>> left('hello world',5) Call the function left(). 'hello' >>>

[2]裝飾器有參數(shù):

a.被裝飾對象無參數(shù):

>>> def test(printResult=False):

def _test(func):

def __test():

print 'Call the function %s().'%func.func_name

if printResult:

print func()

else:

return func()

return __test

return _test

>>> @test(True) def say():return 'hello world'

>>> say() Call the function say(). hello world >>> @test(False) def say():return 'hello world'

>>> say() Call the function say(). 'hello world' >>> @test() def say():return 'hello world'

>>> say() Call the function say(). 'hello world' >>> @test def say():return 'hello world'

>>> say()

Traceback (most recent call last): ? File "", line 1, in ??? say() TypeError: _test() takes exactly 1 argument (0 given) >>>

由上面這段代碼中的最后兩個例子可知:當裝飾器有參數(shù)時,即使你啟用裝飾器的默認參數(shù),不另外傳遞新值進去,也必須有一對括號,否則編譯器會直接將func傳遞給test(),而不是傳遞給_test()

b.被裝飾對象有參數(shù):

>>> def test(printResult=False):

def _test(func):

def __test(*args,**kw):

print 'Call the function %s().'%func.func_name

if printResult:

print func(*args,**kw)

else:

return func(*args,**kw)

return __test

return _test

>>> @test() def left(Str,Len): ??? #The parameters of __test can be '(Str,Len)' in this case. ??? return Str[:Len]

>>> left('hello world',5) Call the function left(). 'hello' >>> @test(True) def left(Str,Len): ??? #The parameters of __test can be '(Str,Len)' in this case. ??? return Str[:Len]

>>> left('hello world',5) Call the function left(). hello >>>

2.裝飾類:被裝飾的對象是一個類

[1]裝飾器無參數(shù):

a.被裝飾對象無參數(shù):

>>> def test(cls):

def _test():

clsName=re.findall('(\w+)',repr(cls))[-1]

print 'Call %s.__init().'%clsName

return cls()

return _test

>>> @test class sy(object): ??? value=32

>>> s=sy() Call sy.__init(). >>> s <__main__.sy object at> >>> s.value 32 >>>

b.被裝飾對象有參數(shù):

>>> def test(cls):

def _test(*args,**kw):

clsName=re.findall('(\w+)',repr(cls))[-1]

print 'Call %s.__init().'%clsName

return cls(*args,**kw)

return _test

>>> @test class sy(object): ??? def __init__(self,value): ??????????????? #The parameters of _test can be '(value)' in this case. ??????? self.value=value

>>> s=sy('hello world') Call sy.__init(). >>> s <__main__.sy object at> >>> s.value 'hello world' >>>

[2]裝飾器有參數(shù):

a.被裝飾對象無參數(shù):

>>> def test(printValue=True):

def _test(cls):

def __test():

clsName=re.findall('(\w+)',repr(cls))[-1]

print 'Call %s.__init().'%clsName

obj=cls()

if printValue:

print 'value = %r'%obj.value

return obj

return __test

return _test

>>> @test() class sy(object): ??? def __init__(self): ??????? self.value=32

>>> s=sy() Call sy.__init(). value = 32 >>> @test(False) class sy(object): ??? def __init__(self): ??????? self.value=32

>>> s=sy() Call sy.__init(). >>>

b.被裝飾對象有參數(shù):

>>> def test(printValue=True):

def _test(cls):

def __test(*args,**kw):

clsName=re.findall('(\w+)',repr(cls))[-1]

print 'Call %s.__init().'%clsName

obj=cls(*args,**kw)

if printValue:

print 'value = %r'%obj.value

return obj

return __test

return _test

>>> @test() class sy(object): ??? def __init__(self,value): ??????? self.value=value

>>> s=sy('hello world') Call sy.__init(). value = 'hello world' >>> @test(False) class sy(object): ??? def __init__(self,value): ??????? self.value=value

>>> s=sy('hello world') Call sy.__init(). >>>

二、類式裝飾器:裝飾器本身是一個類,借用__init__()和__call__()來實現(xiàn)職能

1.裝飾函數(shù):被裝飾對象是一個函數(shù)

[1]裝飾器無參數(shù):

a.被裝飾對象無參數(shù):

>>> class test(object):

def __init__(self,func):

self._func=func

def __call__(self):

return self._func()

>>> @test def say(): ??? return 'hello world'

>>> say() 'hello world' >>>

b.被裝飾對象有參數(shù):

>>> class test(object):

def __init__(self,func):

self._func=func

def __call__(self,*args,**kw):

return self._func(*args,**kw)

>>> @test def left(Str,Len): ??? #The parameters of __call__ can be '(self,Str,Len)' in this case. ??? return Str[:Len]

>>> left('hello world',5) 'hello' >>>

[2]裝飾器有參數(shù)

a.被裝飾對象無參數(shù):

>>> class test(object):

def __init__(self,beforeinfo='Call function'):

self.beforeInfo=beforeinfo

def __call__(self,func):

def _call():

print self.beforeInfo

return func()

return _call

>>> @test() def say(): ??? return 'hello world'

>>> say() Call function 'hello world' >>>

或者:

>>> class test(object):

def __init__(self,beforeinfo='Call function'):

self.beforeInfo=beforeinfo

def __call__(self,func):

self._func=func

return self._call

def _call(self):

print self.beforeInfo

return self._func()

>>> @test() def say(): ??? return 'hello world'

>>> say() Call function 'hello world' >>>

b.被裝飾對象有參數(shù):

>>> class test(object):

def __init__(self,beforeinfo='Call function'):

self.beforeInfo=beforeinfo

def __call__(self,func):

def _call(*args,**kw):

print self.beforeInfo

return func(*args,**kw)

return _call

>>> @test() def left(Str,Len): ??? #The parameters of _call can be '(Str,Len)' in this case. ??? return Str[:Len]

>>> left('hello world',5) Call function 'hello' >>>

或者:

>>> class test(object):

def __init__(self,beforeinfo='Call function'):

self.beforeInfo=beforeinfo

def __call__(self,func):

self._func=func

return self._call

def _call(self,*args,**kw):

print self.beforeInfo

return self._func(*args,**kw)

>>> @test() def left(Str,Len): ??? #The parameters of _call can be '(self,Str,Len)' in this case. ??? return Str[:Len]

>>> left('hello world',5) Call function 'hello' >>>

2.裝飾類:被裝飾對象是一個類

[1]裝飾器無參數(shù):

a.被裝飾對象無參數(shù):

>>> class test(object):

def __init__(self,cls):

self._cls=cls

def __call__(self):

return self._cls()

>>> @test class sy(object): ??? def __init__(self): ??????? self.value=32

>>> s=sy() >>> s <__main__.sy object at> >>> s.value 32 >>>

b.被裝飾對象有參數(shù):

>>> class test(object):

def __init__(self,cls):

self._cls=cls

def __call__(self,*args,**kw):

return self._cls(*args,**kw)

>>> @test class sy(object): ??? def __init__(self,value): ??????? #The parameters of __call__ can be '(self,value)' in this case. ??????? self.value=value

>>> s=sy('hello world') >>> s <__main__.sy object at> >>> s.value 'hello world' >>>

[2]裝飾器有參數(shù):

a.被裝飾對象無參數(shù):

>>> class test(object):

def __init__(self,printValue=False):

self._printValue=printValue

def __call__(self,cls):

def _call():

obj=cls()

if self._printValue:

print 'value = %r'%obj.value

return obj

return _call

>>> @test(True) class sy(object): ??? def __init__(self): ??????? self.value=32

>>> s=sy() value = 32 >>> s <__main__.sy object at> >>> s.value 32 >>>

b.被裝飾對象有參數(shù):

>>> class test(object):

def __init__(self,printValue=False):

self._printValue=printValue

def __call__(self,cls):

def _call(*args,**kw):

obj=cls(*args,**kw)

if self._printValue:

print 'value = %r'%obj.value

return obj

return _call

>>> @test(True) class sy(object): ??? def __init__(self,value): ??????? #The parameters of _call can be '(value)' in this case. ??????? self.value=value

>>> s=sy('hello world') value = 'hello world' >>> s <__main__.sy object at> >>> s.value 'hello world' >>>

總結(jié):【1】@decorator后面不帶括號時(也即裝飾器無參數(shù)時),效果就相當于先定義func或cls,而后執(zhí)行賦值操作func=decorator(func)或cls=decorator(cls);

【2】@decorator后面帶括號時(也即裝飾器有參數(shù)時),效果就相當于先定義func或cls,而后執(zhí)行賦值操作 func=decorator(decoratorArgs)(func)或cls=decorator(decoratorArgs)(cls);

【3】如上將func或cls重新賦值后,此時的func或cls也不再是原來定義時的func或cls,而是一個可執(zhí)行體,你只需要傳入?yún)?shù)就可調(diào)用,func(args)=>返回值或者輸出,cls(args)=>object of cls;

【4】最后通過賦值返回的執(zhí)行體是多樣的,可以是閉包,也可以是外部函數(shù);當被裝飾的是一個類時,還可以是類內(nèi)部方法,函數(shù);

【5】另外要想真正了解裝飾器,一定要了解func.func_code.co_varnames,func.func_defaults,通過它們你可以以func的定義之外,還原func的參數(shù)列表;另外關(guān)鍵字參數(shù)是因為調(diào)用而出現(xiàn)的,而不是因為func的定義,func的定義中的用等號連接的只是有默認值的參數(shù),它們并不一定會成為關(guān)鍵字參數(shù),因為你仍然可以按照位置來傳遞它們。

總結(jié)

以上是生活随笔為你收集整理的python常用的装饰器库_Python中的各种装饰器详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。