一、内建装饰器
包括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