理解基础装饰器
在这一步,我们将介绍装饰器的概念及其基本用法。装饰器是一个接受另一个函数作为参数,添加一些功能,并返回另一个函数的函数,所有这些操作都不改变原始函数的源代码。
首先,在 WebIDE 左侧的文件浏览器中找到文件 decorator_basics.py。双击打开它。我们将在该文件中编写第一个装饰器。
将以下代码复制并粘贴到 decorator_basics.py 中:
import datetime
def log_activity(func):
"""A simple decorator to log function calls."""
def wrapper(*args, **kwargs):
print(f"Calling function '{func.__name__}' at {datetime.datetime.now()}")
result = func(*args, **kwargs)
print(f"Function '{func.__name__}' finished.")
return result
return wrapper
@log_activity
def greet(name):
"""A simple function to greet someone."""
print(f"Hello, {name}!")
## Call the decorated function
greet("Alice")
## Let's inspect the function's metadata
print(f"\nFunction name: {greet.__name__}")
print(f"Function docstring: {greet.__doc__}")
我们来分析一下这段代码:
- 我们定义了一个装饰器函数
log_activity,它接受一个函数 func 作为参数。
- 在
log_activity 内部,我们定义了一个嵌套函数 wrapper。这个函数将包含新的行为。它打印一条日志消息,调用原始函数 func,然后打印另一条日志消息。
log_activity 函数返回 wrapper 函数。
@log_activity 语法位于 greet 函数上方,是 greet = log_activity(greet) 的简写形式。它将我们的装饰器应用于 greet 函数。
现在,保存文件(你可以使用 Ctrl+S 或 Cmd+S)。要运行脚本,请打开 WebIDE 底部的集成终端并执行以下命令:
python ~/project/decorator_basics.py
你将看到以下输出。请注意,日期时间(datetime)会有所不同。
Calling function 'greet' at 2023-10-27 10:30:00.123456
Hello, Alice!
Function 'greet' finished.
Function name: wrapper
Function docstring: None
请注意输出中的两点。首先,我们的 greet 函数现在被包装了日志消息。其次,函数的名称和文档字符串(docstring)已被 wrapper 函数的名称和文档字符串所取代。这对于调试和内省(introspection)来说可能是有问题的。在下一步中,我们将学习如何解决这个问题。