Python装饰器和函数修饰符
Python装饰器和函数修饰符
Python 中的装饰器是一种特殊的函数,它可以修改其他函数的行为。在 Python 中,函数被视为对象。因此,您可以为函数添加属性,函数之间可以传递作为参数,您可以从函数中返回另一个函数等。这给了我们很多有趣的技巧,其中最流行的是将函数作为参数传递并返回其结果的装饰器的实现。
装饰函数的语法
在 Python 中,装饰器是一个函数。使用装饰器时,您需要将要装饰的函数作为参数传递给装饰器功能。然后,装饰器函数修改这个函数,并将其返回。下是一个装饰器的示例。
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
下面是如何调用一个装饰函数:
def say_hello():
print("Hello!")
say_hello = my_decorator(say_hello)
在这个例子中,被修饰的函数是 say_hello。函数名 say_hello 被传递给 my_decorator 函数中被称为“func”的参数。然后,my_decorator 函数创建并返回一个新的函数 wrapper。调用装饰函数后,在变量 say_hello 中存储返回的函数替换原始的 say_hello 函数。现在,当您调用 say_hello 函数时,实际上调用 wrapper 函数,而不是原始的 say_hello 函数。
Python 中的语法糖
Python为装饰函数提供了一种特殊的语法糖。语法糖使得代码更加简洁和易于阅读。使用语法糖,您可以在函数声明上使用 @ 符号,然后将其作为参数传递给装饰器。以下是上面示例的语法糖版本:
@my_decorator
def say_hello():
print("Hello!")
这种语法相当于调用 my_decorator 函数,并将其传递给被修饰的函数。如果要删除装饰器,可以简单地删除注释行 @my_decorator。
应用装饰器的常见用法
装饰器可以执行多种有用的任务。以下是一些最常见的用例。
日志装饰器
日志是一种制定程序的重要方式。您可以使用装饰器添加日志功能,以记录每个函数调用和返回值。以下是一个基本的日志装饰器示例:
import logging
def logging_decorator(func):
def wrapper(*args, **kwargs):
logging.info("function {} called with args {}, kwargs {}".\
format(func.__name__, args, kwargs))
res = func(*args, **kwargs)
logging.info("function {} returned {}".format(func.__name__, res))
return res
return wrapper
@logging_decorator
def add(a, b):
return a + b
这个例子将使用 Python 的内置日志模块。在 @logging_decorator 行之后,函数 add 会被装饰器修饰。现在,每当函数 add 调用时,wrapper 函数将首先输出给定参数的日志记录,然后调用原始的 add 函数。当 add 函数返回时,使用装饰器函数再次记录一条日志,并将结果返回给调用者。
计时器装饰器
装饰器还可以用于在函数中添加定时器功能。这可以帮助您确定特定函数运行所需的时间。下面是一个示例:
import time
def timer_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print("{} func took {} seconds to run.".format(
func.__name__, end_time - start_time))
return res
return wrapper
@timer_decorator
def slow_function():
time.sleep(1)
在这个示例中,装饰函数添加了计时器功能。当您调用修饰过的 slow_function 函数时,它将等待 1 秒钟,然后打印出函数的运行时间,以帮助您测量性能。这个例子可以扩展到任何需要计时器功能的函数。
函数修饰符
在 Python 2 中,您可以使用函数修饰符来实现类似于装饰器的行为。尽管这种方法已经被弃用了,但是在某些情况下,它仍然是有用的。以下是一个函数修饰符的示例:
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
在这个例子中,函数修饰符很像装饰器语法糖。但是,有一个重要的区别:使用函数修饰符时,您需要在装饰器名称之前添加一个 at 符号 @。尽管这种方法已经被弃用,但在某些旧代码库中可能会找到它。
总结
Python 中的装饰器是一个强大的工具,可以完全更改函数的行为。它们可以用于添加功能,包括日志记录、计时器、错误处理等。装饰器可以使用语法糖使代码更简洁易读,并且通过将函数作为参数和返回值,它们提供了许多有趣和灵活的编程技巧。Python 2 中的函数修饰符已经被弃用,但在一些旧代码库中仍然可用,因此您应该了解它们的工作原理。
