欢迎访问宙启技术站
智能推送

Python中的Decorators(装饰器)

发布时间:2023-06-26 18:42:10

Python的装饰器(decorators)是一种非常强大的编程工具。它允许你动态地修改类或函数的行为,在运行时注入代码。

装饰器由特殊的语法和语义组成,它非常灵活。你可以将一个装饰器应用于一个函数或者类,也可以将多个装饰器链接在一起。

装饰器是一个函数,接受一个函数作为参数,并返回一个新的函数。这个新的函数可以是被修改过的,也可以是被包装过的。

下面是一个简单的装饰器示例,它会输出函数的运行时间:

import time

def timing_decorator(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print("Time elapsed: ", end - start)
        return result
    return wrapper

@timing_decorator
def my_function():
    """Do some work here."""
    time.sleep(1)

my_function()  # Time elapsed:  1.0009899139404297

上面的代码定义了timing_decorator函数,它接受一个func参数,这个参数就是要被装饰的函数。

wrapper函数内部,我们记录了当前时间,然后调用被装饰函数,最后计算时间差并打印输出。

my_function函数上面使用了装饰器语法,表示将my_function函数应用于timing_decorator装饰器。现在每次调用my_function函数时,都会自动记录运行时间。

装饰器的语法是@decorator,其实等价于下面的代码:

def my_function():
    """Do some work here."""
    time.sleep(1)

my_function = timing_decorator(my_function)

这里我们将my_function函数传递给timing_decorator函数,然后将返回的新函数赋值给my_function

在这个例子中,我们仅仅实现了一个简单的装饰器。但是,装饰器可以更强大,它可以做很多有用的事情,比如:

- Authentication(身份验证):检查用户是否已经登录或者是否有访问权限。

- Caching(缓存):将函数的执行结果缓存起来,以避免重复计算。

- Logging(日志记录):记录函数的参数、返回值、以及运行时间等信息。

- Retry(重试):在函数失败后,自动进行重试操作。

下面是一个示例,它使用了多个装饰器来实现一个API接口:

from flask import Flask, request, jsonify

app = Flask(__name__)

def require_login(func):
    def wrapper(*args, **kwargs):
        # 检查用户是否登录
        if not request.headers.get('Authorization'):
            return jsonify({'error': 'not authenticated'}), 401
        return func(*args, **kwargs)
    wrapper.__name__ = func.__name__
    return wrapper

def cache_result(func):
    cache = {}

    def wrapper(*args, **kwargs):
        key = str(args) + str(kwargs)
        if key not in cache:
            cache[key] = func(*args, **kwargs)
        return cache[key]
    wrapper.__name__ = func.__name__
    return wrapper

@app.route('/api/greet')
@require_login
@cache_result
def greet():
    name = request.args.get('name', 'World')
    return 'Hello, {}'.format(name)

if __name__ == '__main__':
    app.run(debug=True)

这个例子中,require_login装饰器检查用户是否登录,如果没有登录,则返回一个错误信息。cache_result装饰器使用一个字典来缓存函数执行结果,避免重复计算。

最后,我们使用多个装饰器来装饰greet函数,这个函数接受一个name参数,如果没有传递则默认为World

如果你在调用greet时不传递name参数,那么它会返回Hello, World。如果你登录并多次调用greet函数,则只会执行一次计算。

装饰器是Python中非常有用的编程工具,它们可以用来修改函数或者类的行为。它们可以在运行时注入代码,帮助你简化代码,实现复杂的功能。