Python装饰器学习(二)

类方法的装饰

注意类方法的装饰和普通函数不同,方法还有第一个参数self,即类实例。

下面是一个例子,比较好理解。我这个装饰器主要是把scrapy爬取的类变成Python字典,存储到数据库中。

def decorator(method):
    def to_dict(decorated_instance, item):
        result = {}
        for key in item:
            result[key] = item[key]
            if isinstance(item[key], CompanyItem):
                company = {}
                for ele in result[key]:
                    company[ele] = result[key][ele]
                result[key] = company
        method(decorated_instance,result)

    return to_dict



class Deco(object):

    @decorator
    def deco(self,item):
        for key in item:
            print key, item[key]


if __name__== "__main__":

    s = Deco()
    s.deco({'s':3})

也就是说,类的方法必须要带有一个类实例本身的参数。

装饰类

上面介绍了很多装饰函数的装饰器,下面介绍一下装饰类的装饰器。其实这和装饰函数差不多,只不过是被装饰的是类,返回的是一个类,而不是一个函数。

def decorator(oneclass):
    class newclass():
        def __init__(self,name):
            self.name = name
            self.total = 0
            self.wrapper = oneclass(name)

        def visit(self):
            self.total += 1
            print 'the wrapped class print the totoal %d' % self.total
            self.wrapper.visit()
    return newclass


@decorator
class A(object):
    def __init__(self,name):
        self.name = name

    def visit(self):
        print 'the original class'



s = A('haibo')
s.visit()

类装饰器

上面不管装饰类还是装饰函数,装饰器本身是一个函数,现在说说类装饰器。

class decorator(object):
def __init__(self,desp='function'):
    self.desp = desp

def __call__(self, func):
    def wrapped(*args,**kwargs):
        print self.desp
        func(*args,**kwargs)
    return wrapped


@decorator()
def func(*args):
    print args

func(3)

上面的代码有几点需要注意:

1、如果装饰器本身带参数,那装饰函数的时候不管你写不写参数都要加上括号,否则不能正常运行;
2、类装饰器是通过 init ()和 call ()来实现。

上面的例子是装饰器本身带参数,被装饰的函数也带参数,再看个例子。

class decorator(object):
    def __init__(self,func):
        self.func = func

    def __call__(self,*args):
        return self.func(*args)


@decorator
def func(*args):
    print args

func(3)

装饰器的调用顺序:装饰器的调用顺序与@ 语法声明的顺序正好相反。

@deco1
@deco2
def func():
   .....

上面的装饰相当于:func()=deco1(deco2(func))。

--------EOF---------
微信分享/微信扫码阅读