Python之装饰器

 一 装饰是什么

装饰器是 闭包函数的一种应用,只不过其传递的是函数。装饰器的返回值也是一个函数对象。

装饰器原则:

装饰器原则:1、不修改被装饰对象的 源代码  
               2、不修改被装饰对象的 调用方式

达到的目标: 在遵循1和2的前提下,为被装饰对象添加新功能        

 

简而言之:@a 就是将 b 传递给 a(),并返回新的 b = a(b)

import time

def timer(func):
    def internal(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)
        stop_time = time.time()
        print('run time is {}'.format(stop_time - start_time))
        return res
    return internal


@timer            #相当于 test = timer(test)
def test():
    time.sleep(3)
    print('Hello World')

test()


#结果:
# Hello World
# run time is 3.0008761882781982

二 装饰器的使用:

import time

def timer(func):
    def internal(*args,**kwargs):
        start_time = time.time()
        res = func()
        stop_time = time.time()
        print('run time is {}'.format(stop_time - start_time))
        return res
    return internal

@timer
def test():
    time.sleep(3)
    print('from test')

test()
无参装饰器
def auth2(auth_type):
    def auth(func):
        def internal(*args,**kwargs):
            if auth_type == 'file':
                name = input('username:')
                pwd = input('password:')
                if name == 'tom' and pwd == '123':
                    print('Auth Success')
                    res = func(*args,**kwargs)
                    return res
                else:
                    print('Auth error')
            elif auth_type == 'sql':
                print('sql 先停停')
        return internal
    return auth

@auth2(auth_type='file')
def index():
    print('Hello')

index()
有参装饰器

 

三 wrapper返回的不是原函数的帮助信息

当我们使用了装饰器的时候,虽然没有修改代码本身,但是在运行的时候,比如上面这个例子,运行index其实在运行internal了,如果我们打印my_index的注释信息,会打印internal的注释信息,那么该如何处理?

 
import time

def timer(func):
    def internal():
        """计算运行时间"""
        stat_time = time.time()
        res = func()
        stop_time = time.time()
        print('run time is {}'.format(stop_time - stat_time))
        return res
    return internal

@timer
def index():
    """世界 你好"""            #原始注释信息
    print('Hello World')

index()
print(index.__doc__)


#结果:
Hello World
run time is 0.0
计算运行时间               #并不是想要的 





解决方法:

import time
from functools import wraps

def timer(func):
    @wraps(func)
    def internal():
        """计算运行时间"""
        stat_time = time.time()
        res = func()
        stop_time = time.time()
        print('run time is {}'.format(stop_time - stat_time))
        return res
    return internal

@timer
def index():
    """世界 你好"""
    print('Hello World')
    time.sleep(1)

index()
print(index.__doc__)


#结果:
Hello World
run time is 1.0004730224609375
世界 你好


原文地址:https://www.cnblogs.com/zhaochangbo/p/6691813.html