Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

python 装饰器 #24

Open
sfPPP opened this issue Aug 16, 2018 · 0 comments
Open

python 装饰器 #24

sfPPP opened this issue Aug 16, 2018 · 0 comments

Comments

@sfPPP
Copy link
Owner

sfPPP commented Aug 16, 2018

python装饰器

装饰器是一个很著名的设计模式,经常被用于AOP(面向切面编程)的场景,较为经典的有插入日志,性能测试,事务处理,Web权限校验, Cache等。


from functools import wraps

def my_decorator(f):
    @wraps(f)
    def wrapper(*args, **kwds):
        print "Calling decorated function"
        print f.__name__

        return f(*args, **kwds)

    return wrapper

@my_decorator
def example():
    """DocString"""
    print "Called example function"

example()
print example.__name__
print example.__doc__

控制台输出:

Calling decorated function
example
Called example function
example
DocString

可以看到,最终调用函数example时,是经过 @my_decorator装饰的,装饰器的作用是接受一个被包裹的函数作为参数,对其进行加工,返回一个包裹函数,代码使用 @functools.wraps装饰将要返回的包裹函数wrapper,使得它的 name, module,和 doc 属性与被装饰函数example完全相同,这样虽然最终调用的是经过装饰的example函数,但是某些属性还是得到维护。
如果在 @my_decorator的定义中不使用 @function.wraps装饰包裹函数,那么最终example.name 将会变成'wrapper',而example.doc 也会丢失。


Calling decorated function
example
Called example function
wrapper
None

比如我们统计某函数执行时间,并输出日志:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import functools
import time


def wrap_performance(func):
    @functools.wraps(func)
    def wrapper(self, *args, **kwargs):
        t_begin = time.time()
        print 'before'
        result = func(self, *args, **kwargs)
        print 'end'
        t_end = time.time()
        print("Time: %f " % (t_end - t_begin))
        return result

    return wrapper


class Test:
    def __init__(self):
        pass

    @wrap_performance
    def test(self):
        time.sleep(1)


t = Test()
t.test()

输出结果为:

before
end
Time: 1.001000

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant