python 類修飾器


1. 修改類函數。

場景: 如果要給一個類的所有方法加上計時,並打印出來。demo如下:

# -*- coding:utf-8 -*-
import time
def time_it(fn):
    "Example of a method decorator"
    def decorator(*args, **kwargs):
    t1=time.time()
        ret = fn(*args, **kwargs)
    print '\t\t%d seconds taken for %s'%(time.time()-t1, fn.__name__)
    return ret

    return decorator

def class_decorator(*method_names):
    def class_rebuilder(cls):
        "The class decorator example"
        class NewClass(cls):
            "This is the overwritten class"
            def __getattribute__(self, attr_name):
                attr_val = super(NewClass, self).__getattribute__(attr_name)
                if callable(attr_val) and attr_name in method_names:
                    return time_it(attr_val)
                return attr_val

        return NewClass
    return class_rebuilder

@class_decorator('first_method', 'second_method')
class MySecondClass(object):
    """
    This class is decorated
    """
    def first_method(self, *args, **kwargs):
        print "\tthis is a the MySecondClass.first_method"
    time.sleep(2)

    def second_method(self, *args, **kwargs):
        print "\tthis is the MySecondClass.second_method"
    time.sleep(1)

if __name__ == "__main__":
    print "::: With a decorated class :::"
    z = MySecondClass()
    z.first_method()
    z.second_method()

 

好處相比函數修飾器要稍微簡潔一點(在類有很多方法時)

 

2. 增加類成員

場景:比如統一給所有的模型增加id, created_time屬性

# -*- coding:utf-8 -*-
def addAttrs(*attrs):
    def re_build(cls):
        class newClass(cls):
            def __init__(self,*args, **kws):
                for attr in attrs:
            setattr(self, attr, None)
                self.__id = id
                super(newClass, self).__init__(*args, **kws)
        return newClass
    return re_build

@addAttrs('id', 'created_time')
class DBModelOne(object):
    def __init__(self, *args, **kwargs):
        pass

if __name__=='__main__':
    m = DBModelOne(5)
    print m.id, m.created_time

 

or

# -*- coding:utf-8 -*-
import time
def cd(cls):
    def init(*args, **kwargs):
        cls_obj = cls(*args, **kwargs)
        setattr(cls_obj, 'id', time.time())
        return cls_obj
    return init
@cd
class A(object):
    def __init__(self, name, age, sex='f'):
        self.name=name
        self.age=age
        self.sex=sex
    def s(self):
        print self.id

if __name__=='__main__':
    print type(A)#<type 'function'>
    a=A('Alice', 22)
    print type(a)#<class '__main__.A'>
    print a#<__main__.A object at 0x7fe617baa690>
    print a.name, a.age, a.sex#Alice 22 f
    a.s()

 

 

轉載請注明來自:http://www.cnblogs.com/Tommy-Yu/p/5457751.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM