一、内建装饰器
包括property,classmethod,staticmethod
classmethod与s taticmethod
class deco_test:
@staticmethod
def test_static():
print 'class test static'
def test_normal(self):
print "normal"
@classmethod
def test_class(cls):
print "class",cls
def test_static_method():
print "global test static"
deco=deco_test()
test_static_method()
deco_test.test_static()
deco.test_static()
deco.test_normal()
deco.test_class()
print deco_test
print deco
结果:
global test static
class test static
class test static
normal
class __main__.deco_test
__main__.deco_test
<__main__.deco_test instance at 0x7f46e46c63f8>
staticmethod装饰器,类实例和对象都可以访问,和类中的普通方法相比,不带self参数,可以用全局方法代替
classmethod将类自己作为对象传给class方法,
>>> class A:
... @classmethod
... def test_class(cls):
... return cls
...
>>> a=A()
>>> a.test_class()
<class __main__.A at 0x7ff898f7e188>
>>> A
<class __main__.A at 0x7ff898f7e188>
property:使用方法
class rabbit(object):
def __init__(self,name):
self._name=name
#set read attrib
@property
def name(self):
return self._name
#set write attrib
@name.setter
def name(self,name):
self._name=name
#set del attrib
@name.deleter
def name(self):
del self._name
ra=rabbit("kyle")
print ra.name
#write
ra.name="kate"
print ra.name
#del
del ra.name
try:
print ra.name
except AttributeError ,e:
print e
结果
kyle
kate
'rabbit' object has no attribute '_name'
使用property后,方法就变成了类的属性,默认情况下是有读属性,如果要有写和删除的话,需按@functionname.setter,@functionname.deleter设置
二、自定义装饰器
首先说明函数在python中也是对象,也能作为函数返回值,先理解这点,装饰器就好明白了。
def deco1(func):
def warpper(*args,**kwargs):
print "before"
func(*args,**kwargs)
print "after"
return warpper
@deco1
def foo(x):
print x
foo(1)
结果:
before
1
after
如果还不是很明白,换一种写法就明白了
def deco1(func):
def warpper(*args,**kwargs):
print "before"
func(*args,**kwargs)
print "after"
return warpper
def foo(x):
print x
foo=deco1(foo)
foo(1)
返回结果同上面一样,其实可以理解为被装饰的函数对象传递给装饰函数,并返回同被装饰函数相同名字的函数对象
多重装饰
def deco1(func):
def warpper(*args,**kwargs):
print "before"
func(*args,**kwargs)
print "after"
return warpper
def deco2(func):
def wraper(*args,**kwargs):
print "yes"
func(*args,**kwargs)
print "no"
return wraper
@deco1
@deco2
def foo1(x,y):
print (x,y)
foo1(1,2)
结果:
before
yes
(1, 2)
no
after
多重装饰的话注意顺序就ok