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

Python中的装饰器函数:如何使用和实现

发布时间:2023-06-16 09:39:45

装饰器函数是一种高级概念,它可以让程序员在不改变被装饰函数源代码的情况下,通过添加一些修饰或增强功能的方式,使得被修饰的函数更加强大、灵活和易于维护。在Python中,装饰器通常用于对函数进行封装、时间统计、缓存、日志记录、输入检查、权限控制等方面。本文将介绍如何使用和实现Python中的装饰器函数。

一、如何使用装饰器函数

使用装饰器函数的方式非常简单,只需要在被装饰的函数上方添加@符号,然后接上装饰器函数名称即可。例如,下面是一个简单的装饰器函数,它能够在函数执行之前和之后打印出当前时间:

import time

def timeit(func):
    def wrapper(*args, **kwargs):
        print('开始时间:', time.strftime('%Y-%m-%d %H:%M:%S'))
        result = func(*args, **kwargs)
        print('结束时间:', time.strftime('%Y-%m-%d %H:%M:%S'))
        return result
    return wrapper

@timeit
def foo():
    time.sleep(1)
    print('执行函数foo')

foo()

上述代码中,我们定义了一个名为timeit的装饰器函数,它接收一个函数对象作为参数,然后返回一个新的函数对象wrapper,该对象能够在被装饰函数执行之前和之后打印出当前时间。通过在foo函数上方添加@timeit装饰器,我们就可以将原来的函数变成了经过增强的新函数,在执行时会自动打印出开始时间和结束时间。

二、如何实现装饰器函数

实现装饰器函数的过程其实就是定义一个函数,它接收被装饰的函数对象作为参数,然后返回一个新的函数对象,新函数对象可以在被装饰函数执行前后增加一些额外的逻辑。下面是一个常见的装饰器函数模板:

def decorator(func):
    def wrapper(*args, **kwargs):
        # 被装饰函数执行前的逻辑
        result = func(*args, **kwargs)
        # 被装饰函数执行后的逻辑
        return result
    return wrapper

其中,decorator函数是我们自定义的装饰器函数,它接收一个参数func,该参数是被装饰的函数对象。wrapper函数是我们新定义的函数对象,它通过调用被装饰函数,并额外添加了一些逻辑,最后返回被装饰函数的执行结果。

常用的装饰器函数有以下几种:

1. 修饰函数

def bold(func):
    def wrapper(*args, **kwargs):
        return "<b>" + func(*args, **kwargs) + "</b>"
    return wrapper

@bold
def hello(name):
    return "Hello, " + name + "!"

print(hello("world"))  # 输出:"<b>Hello, world!</b>"

2. 时间统计函数

def timeit(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print("函数%s的执行时间为%f秒" % (func.__name__, end-start))
        return result
    return wrapper

@timeit
def foo():
    time.sleep(1)

foo()  # 输出:函数foo的执行时间为1.002363秒

3. 日志记录函数

def logger(filename):
    def decorator(func):
        def wrapper(*args, **kwargs):
            with open(filename, mode="a", encoding="utf-8") as f:
                f.write(f"执行函数{func.__name__}的时间:{time.strftime('%Y-%m-%d %H:%M:%S')}
")
            return func(*args, **kwargs)
        return wrapper
    return decorator

@logger("log.txt")
def foo():
    time.sleep(1)

foo()  # 在log.txt文件中记录函数执行的时间

4. 缓存函数

def cache(func):
    cached = {}

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

    return wrapper

@cache
def foo(a, b):
    time.sleep(1)
    return a + b

print(foo(1, 2))  # 耗时1s,输出3
print(foo(1, 2))  # 不耗时,直接输出3

5. 输入检查函数

def check_input(func):
    def wrapper(*args, **kwargs):
        for arg in args:
            if not isinstance(arg, (int, float)):
                raise TypeError("参数必须是数字类型")
        return func(*args, **kwargs)
    return wrapper

@check_input
def foo(a, b):
    return a + b

print(foo(1, 2))  # 输出3
print(foo("1", 2))  # TypeError: 参数必须是数字类型

6. 权限控制函数

def check_permission(func):
    def wrapper(*args, **kwargs):
        if not user_has_permission():
            raise PermissionError("无权限执行此操作")
        return func(*args, **kwargs)

    return wrapper

@check_permission
def foo():
    return "执行foo操作"

print(foo())  # 如果没有权限,会raise PermissionError异常

以上就是使用和实现Python中装饰器函数的简单介绍,希望对读者有所帮助。