zoukankan      html  css  js  c++  java
  • 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 '		%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 "	this is a the MySecondClass.first_method"
        time.sleep(2)
    
        def second_method(self, *args, **kwargs):
            print "	this 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

  • 相关阅读:
    jenkins log日志过大
    USB Key
    银行应用USB Key身份认证方案
    安全登录认证
    加密和认证
    C#中的委托(Delegate)和事件(Event)
    白皮书、蓝皮书、绿皮书、黄皮书、褐皮书
    DevExpress GridControl使用方法总结
    private protected internal public
    android尺寸问题(转)
  • 原文地址:https://www.cnblogs.com/Tommy-Yu/p/5457751.html
Copyright © 2011-2022 走看看