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

了解Python装饰器函数及其用法

发布时间:2023-06-19 00:24:07

装饰器是Python语言中用来修改函数或类的行为的一项特性。它是一种函数,可以接收另一个函数作为参数,并返回另一个函数。通俗地说,装饰器就是一种可以装饰函数的函数。使用装饰器,我们可以很方便地为已有的函数添加新的功能或修改原有的功能而不用修改原函数的代码。

装饰器函数的基本形式:

def decorator_function(original_function):
    def decorated_function(*args, **kwargs):
        # 在这里添加新的功能
        return original_function(*args, **kwargs)
    return decorated_function

上面的代码定义了一个装饰器函数,它可以为任意一个函数添加新的功能而不用修改原函数的代码。decorator_function函数接收原函数作为参数,并返回一个新的函数。在这个新的函数中,我们可以添加一些新的代码,比如打印函数的参数、计算函数的运行时间、检查函数的输入等等。最后返回原函数的运行结果。

下面是一个例子,实现了一个简单的计时器装饰器:

import time

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print('函数 %s 运行时间为 %.2f 秒' % (func.__name__, end_time - start_time))
        return result
    return wrapper

@timer
def my_function():
    time.sleep(1)

my_function()

这个装饰器在函数执行前记录了起始时间,在函数执行后计算了时间的差值,并打印出函数名及运行时间。使用装饰器的语法糖@timer可以将my_function函数传递给装饰器函数timer,实现计时器的功能。

Python中还有很多内置的装饰器,比如classmethod、staticmethod、property等。我们也可以自己编写装饰器来添加对原函数的扩展功能。装饰器的函数签名可以是任意的,只要它接收一个函数作为参数,并返回一个新的函数即可。

装饰器还可以用来实现针对类的装饰器,装饰器可以对类的方法进行装饰,从而实现添加新功能或修改原有功能。比如,可以定义一个日志记录器的装饰器:

def logger(cls):
    for name in cls.__dict__:
        func = getattr(cls, name)
        if callable(func) and not name.startswith('__'):
            setattr(cls, name, logged(func, name))
    return cls

def logged(func, name):
    def wrapper(*args, **kwargs):
        print('%s 方法被调用了' % name)
        return func(*args, **kwargs)
    return wrapper

@logger
class MyClass:
    def my_method(self):
        pass

这个装饰器定义了一个logger函数,它接收一个类作为参数,并使用反射机制遍历类的所有方法,对每个方法应用logged装饰器。logged装饰器在每个方法被调用时打印出方法名,并调用原方法返回结果。

使用装饰器可以非常方便地扩展或修改已有的函数或类,从而实现更灵活的功能。但需要注意的是,装饰器可能会影响函数的运行效率,因此需要谨慎处理装饰器的使用。