Python装饰器,分两部分,一是装饰器本身的定义,一是被装饰器对象的定义。
一、函数式装饰器:装饰器本身是一个函数。
1.装饰函数:被装饰对象是一个函数
[1]装饰器无参数:
a.被装饰对象无参数:
代码如下:
>>> 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.被装饰对象有参数:
代码如下:
>>> 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]装饰器有参数:
a.被装饰对象无参数:
代码如下:
>>> 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 "
say()
TypeError: _test() takes exactly 1 argument (0 given)
>>>
由上面这段代码中的最后两个例子可知:当装饰器有参数时,即使你启用装饰器的默认参数,不另外传递新值进去,也必须有一对括号,否则编译器会直接将func传递给test(),而不是传递给_test()
b.被装饰对象有参数:
代码如下:
>>> 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]装饰器无参数:
a.被装饰对象无参数:
代码如下:
>>> 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.被装饰对象有参数:
代码如下:
>>> 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]装饰器有参数:
a.被装饰对象无参数:
代码如下:
>>> 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.被装饰对象有参数:
代码如下:
>>> 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__()来实现职能
1.装饰函数:被装饰对象是一个函数
[1]装饰器无参数:
a.被装饰对象无参数:
代码如下:
>>> 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.被装饰对象有参数:
代码如下:
>>> 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]装饰器有参数
a.被装饰对象无参数:
代码如下:
>>> 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.被装饰对象有参数:
代码如下:
>>> 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]装饰器无参数:
a.被装饰对象无参数:
代码如下:
>>> 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.被装饰对象有参数:
代码如下:
>>> 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]装饰器有参数:
a.被装饰对象无参数:
代码如下:
>>> 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.被装饰对象有参数:
代码如下:
>>> 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'
>>>
总结:【1】@decorator后面不带括号时(也即装饰器无参数时),效果就相当于先定义func或cls,而后执行赋值操作func=decorator(func)或cls=decorator(cls);
【2】@decorator后面带括号时(也即装饰器有参数时),效果就相当于先定义func或cls,而后执行赋值操作 func=decorator(decoratorArgs)(func)或cls=decorator(decoratorArgs)(cls);
【3】如上将func或cls重新赋值后,此时的func或cls也不再是原来定义时的func或cls,而是一个可执行体,你只需要传入参数就可调用,func(args)=>返回值或者输出,cls(args)=>object of cls;
【4】最后通过赋值返回的执行体是多样的,可以是闭包,也可以是外部函数;当被装饰的是一个类时,还可以是类内部方法,函数;
【5】另外要想真正了解装饰器,一定要了解func.func_code.co_varnames,func.func_defaults,通过它们你可以以func的定义之外,还原func的参数列表;另外关键字参数是因为调用而出现的,而不是因为func的定义,func的定义中的用等号连接的只是有默认值的参数,它们并不一定会成为关键字参数,因为你仍然可以按照位置来传递它们。

Pythonlistsareimplementedasdynamicarrays,notlinkedlists.1)Theyarestoredincontiguousmemoryblocks,whichmayrequirereallocationwhenappendingitems,impactingperformance.2)Linkedlistswouldofferefficientinsertions/deletionsbutslowerindexedaccess,leadingPytho

Pythonoffersfourmainmethodstoremoveelementsfromalist:1)remove(value)removesthefirstoccurrenceofavalue,2)pop(index)removesandreturnsanelementataspecifiedindex,3)delstatementremoveselementsbyindexorslice,and4)clear()removesallitemsfromthelist.Eachmetho

Toresolvea"Permissiondenied"errorwhenrunningascript,followthesesteps:1)Checkandadjustthescript'spermissionsusingchmod xmyscript.shtomakeitexecutable.2)Ensurethescriptislocatedinadirectorywhereyouhavewritepermissions,suchasyourhomedirectory.

ArraysarecrucialinPythonimageprocessingastheyenableefficientmanipulationandanalysisofimagedata.1)ImagesareconvertedtoNumPyarrays,withgrayscaleimagesas2Darraysandcolorimagesas3Darrays.2)Arraysallowforvectorizedoperations,enablingfastadjustmentslikebri

Arraysaresignificantlyfasterthanlistsforoperationsbenefitingfromdirectmemoryaccessandfixed-sizestructures.1)Accessingelements:Arraysprovideconstant-timeaccessduetocontiguousmemorystorage.2)Iteration:Arraysleveragecachelocalityforfasteriteration.3)Mem

Arraysarebetterforelement-wiseoperationsduetofasteraccessandoptimizedimplementations.1)Arrayshavecontiguousmemoryfordirectaccess,enhancingperformance.2)Listsareflexiblebutslowerduetopotentialdynamicresizing.3)Forlargedatasets,arrays,especiallywithlib

Mathematical operations of the entire array in NumPy can be efficiently implemented through vectorized operations. 1) Use simple operators such as addition (arr 2) to perform operations on arrays. 2) NumPy uses the underlying C language library, which improves the computing speed. 3) You can perform complex operations such as multiplication, division, and exponents. 4) Pay attention to broadcast operations to ensure that the array shape is compatible. 5) Using NumPy functions such as np.sum() can significantly improve performance.

In Python, there are two main methods for inserting elements into a list: 1) Using the insert(index, value) method, you can insert elements at the specified index, but inserting at the beginning of a large list is inefficient; 2) Using the append(value) method, add elements at the end of the list, which is highly efficient. For large lists, it is recommended to use append() or consider using deque or NumPy arrays to optimize performance.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

SublimeText3 English version
Recommended: Win version, supports code prompts!

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

Dreamweaver CS6
Visual web development tools

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft
