Python cookbook进阶学习-元编程(一)

来源:互联网 发布:淘宝正义哥海外代购 编辑:程序博客网 时间:2024/06/13 10:33

一、在函数上添加包装器

import timefrom functools import wrapsdef timethis(func):    '''    decorator that reports the execution time.    '''    @wraps(func)    def wrapper(*args, **kwargs):        start = time.time()        result = func(*args, **kwargs)        end = time.time()        print(func.__name__, end-start)        return result    return wrapper@timethisdef countdown(n):    while n > 0:        n = n-1

使用内置装饰器
1.wraps保留函数元信息,能通过wrapped属性直接访问被包装函数,在底层访问到函数签名等信息。
2.property获取属性
3.setter和getter
4.classmethod类方法 staticmethod 静态方法

class Student(object):    def __init__(self, name):        self._name = name    @property    def name(self):        return self._name    @name.setter    def name(self, value):        if value is not None:            self._name = value    @classmethod           def fun1(cls):        pass    @staticmethod    def fun2():        pass

二、带参数的装饰器

from functools import wrapsimport loggingdef logged(level, name=None, message=None):    def decorate(func):        logname = name if name else func.__module__        log = logging.getLogger(logname)        logmsg = message if message else func.__name__        @wraps(func)        def wrapper(*args, **kwargs):            log.log(level, logmsg)            return func(*args, **kwargs)        return wrapper    return decorate@logged(logging.DEBUG)def add(x, y):    return x+y@logged(logging.CRITICAL, 'example')def spam():    print('spam')

三、可自定义属性的装饰器
使用nonlocal

from functools import partial, wrapsimport loggingdef attach_wrapper(obj, func=None):    if func is None:        return partial(attach_wrapper, obj)    setattr(obj, func.__name__, func)    return funcdef logged(level, name=None, message=None):    def decorate(func):        logname = name if name else func.__module__        log = logging.getLogger(logname)        logmsg = message if message else func.__name__        @wraps(func)        def wrapper(*args, **kwargs):            log.log(level, logmsg)            return func(*args, **kwargs)        @attach_wrapper(wrapper)        def set_level(newlevel):            nonlocal level            level = newlevel        @attach_wrapper(wrapper)        def set_message(newmsg):            nonlocal message            message = newmsg        return wrapper    return decorate

使用例子
这里写图片描述

原创粉丝点击