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

Python装饰器函数-如何在代码中重用相同的功能

发布时间:2023-06-20 06:59:57

Python的装饰器函数可以让开发者在代码中重用相同的功能,提高代码重用性和可维护性。本文将详细介绍Python装饰器函数的概念、用法和使用场景。

一、Python装饰器函数的概念

Python装饰器函数是一种特殊的函数,其可以在不改变原函数代码的情况下,在函数执行前或执行后插入一些其他的代码。装饰器函数本身也是一个函数,它以被装饰的函数为参数,并且返回一个新的函数。

Python装饰器函数有以下特点:

1. 装饰器函数可以被另外一个函数或方法调用。

2. 装饰器函数的返回值也是一个函数。

3. 装饰器函数可以对原函数增加或删除一些功能。

4. 装饰器函数可以对原函数的参数进行修改。

5. 装饰器函数的执行顺序与装饰的顺序相反。

二、Python装饰器函数的用法

Python装饰器函数的语法格式如下:

@decorator_function
def original_function(arguments):
    # Function body

其中,@decorator_function表示使用该装饰器函数对original_function进行装饰。

下面是一个装饰器函数的例子:

def my_decorator(original_function):
    def wrapper_function(*args, **kwargs):
        print("Before the function is called.")
        result = original_function(*args, **kwargs)
        print("After the function is called.")
        return result
    return wrapper_function

@my_decorator
def greet(name):
    print("Hello, " + name + "!")
    
greet("World")

上面的代码中,my_decorator是一个装饰器函数,它将wrapper_function作为返回值。wrapper_function是一个新的函数,它在original_function执行前后输出一些内容。greet函数被@my_decorator装饰,相当于greet = my_decorator(greet)。在调用greet("World")时,会输出以下内容:

Before the function is called.
Hello, World!
After the function is called.

三、Python装饰器函数的使用场景

1. 记录函数执行过程,包括函数参数和返回值。

def logger(original_function):
    def wrapper_function(*args, **kwargs):
        print(f"Function {original_function.__name__} is called.")
        print(f"Arguments: {args}, {kwargs}")
        result = original_function(*args, **kwargs)
        print(f"Result: {result}")
        return result
    return wrapper_function

@logger
def multiply(a, b):
    return a * b

multiply(3, 4)

输出:

Function multiply is called.
Arguments: (3, 4), {}
Result: 12

2. 记录函数执行时间。

import time

def timer(original_function):
    def wrapper_function(*args, **kwargs):
        start_time = time.time()
        result = original_function(*args, **kwargs)
        end_time = time.time()
        print(f"Function execution time: {end_time - start_time} seconds.")
        return result
    return wrapper_function

@timer
def countdown(n):
    while n > 0:
        print(n)
        n -= 1
        time.sleep(1)
    print("Blastoff!")

countdown(5)

输出:

5
4
3
2
1
Blastoff!
Function execution time: 5.0037641525268555 seconds.

3. 检查函数参数合法性。

def validator(*types):
    def decorator_function(original_function):
        def wrapper_function(*args, **kwargs):
            for i, arg in enumerate(args):
                if not isinstance(arg, types[i]):
                    raise TypeError(f"Argument {i+1} is not of type {types[i]}")
            return original_function(*args, **kwargs)
        return wrapper_function
    return decorator_function

@validator(int, str)
def bar(num, text):
    print(f"num: {num}, text: {text}")

bar(1, "Hello")
bar(1.0, "World")  # TypeError: Argument 1 is not of type <class 'int'>

输出:

num: 1, text: Hello
Traceback (most recent call last):
  File "test.py", line 16, in <module>
    bar(1.0, "World")
  File "test.py", line 8, in wrapper_function
    raise TypeError(f"Argument {i+1} is not of type {types[i]}")
TypeError: Argument 1 is not of type <class 'int'>

4. 权限控制。

def access_control(role):
    def decorator_function(original_function):
        def wrapper_function(*args, **kwargs):
            if role == "admin":
                return original_function(*args, **kwargs)
            else:
                print(f"Access denied for {role}.")
        return wrapper_function
    return decorator_function

@access_control("user")
def admin_page():
    print("This is the admin page.")

admin_page()  # Access denied for user.

输出:

Access denied for user.

以上是Python装饰器函数的概念、用法和使用场景的详细说明。通过装饰器函数,我们可以轻松地实现代码重用和功能扩展。