python 9-5 如何在类中定义装饰器,在包裹函数中就可以持有实例对象,便于修改属性和功能

9-5 如何在类中定义装饰器
解决方案:
为了让装饰器在使用上更加灵活,可以把类的实例方法作为装饰器
此时在包裹函数中就可以持有实例对象,便于修改属性和功能

import logging
from time import  localtime,time,strftime,sleep
class CallingInfo(object):
    def __init__(self,name):
        log = logging.getLogger(name)
        log.setLevel(logging.INFO)
        fh = logging.FileHandler(name + '.log')
        log.addHandler(fh)
        log.info("start...".center(50,'-'))
        self.log = log
        self.formatter = '%(func)s ->[%(time)s - %(used)s - %(ncalls)s -]'

    def info(self,func):
        def wrapper(*args,**kwargs):
            wrapper.ncalls += 1
            lt = localtime()
            start = time()
            res = func(*args,**kwargs)
            used = time() - start
            info = {}
            info['func'] = func.__name__
            info['time'] = strftime('%x %X',lt)
            info['used'] = used
            info['ncalls'] = wrapper.ncalls
            msg = self.formatter % info
            self.log.info(msg)
            return res
        wrapper.ncalls = 0

        return wrapper
    def setFormater(self,formatter):
        self.formatter = formatter

    def turnOn(self):
        log.setLevel(logging.INFO)

    def turnOff(self):
        self.log.setLevel(logging.WARN)



cinfo1 = CallingInfo('mylog1')
cinfo2 = CallingInfo('myLog2')
cinfo1.setFormater('%(func)s ->[%(time)s - %(used)s - %(ncalls)s -]')
cinfo2.turnOff()

@cinfo1.info
def f():
    print "in f"

@cinfo1.info
def g():
    print 'in g'

@cinfo2.info
def h():
    print 'in h'
from random import choice
for _ in xrange(50):
    choice([f,g,h])()
    sleep(choice([0.5,1,1.5]))

你可能感兴趣的:(python实战)