介绍
在这个实验中,你将通过探索函数签名来学习如何检查一个 Python 函数是否接受特定的参数。本实验利用 inspect 模块来访问和检查函数签名,提供有关函数预期参数和返回值的有用信息。
本实验将引导你创建一个包含示例函数的 Python 脚本,然后使用 inspect.signature() 来获取并打印函数的签名。你还将学习如何解读输出,以了解函数的参数和返回类型。最后,本实验将演示如何使用 try-except 块来测试参数传递。
了解函数签名
在这一步中,你将了解 Python 中的函数签名。函数签名提供了有关函数预期参数和返回值的重要信息。理解函数签名对于编写简洁、可维护且无错误的代码至关重要。
函数签名包含以下信息:
- 函数名称:函数的名称。
- 参数:函数接受的参数的名称和类型。
- 返回类型:函数返回的值的类型(如果有)。
Python 提供了多种访问和检查函数签名的方法。最常用且强大的方法之一是使用 inspect 模块。让我们来探索如何使用 inspect 模块来了解函数签名。
首先,使用 VS Code 编辑器在你的 ~/project 目录中创建一个名为 my_function.py 的简单 Python 脚本。这个脚本将定义一个函数,然后使用 inspect 模块来检查其签名。
## filename: ~/project/my_function.py
import inspect
def add_numbers(x: int, y: int) -> int:
"""This function adds two numbers and returns the result."""
return x + y
sig = inspect.signature(add_numbers)
print(sig)
在这个脚本中:
- 我们导入了
inspect模块。 - 我们定义了一个名为
add_numbers的函数,它接受两个整数参数(x和y),并返回它们的和作为整数。 - 我们使用类型提示(
x: int、y: int、-> int)来指定参数和返回值的预期类型。 - 我们使用
inspect.signature()来获取add_numbers函数的签名,并将其存储在sig变量中。 - 我们将签名打印到控制台。
现在,让我们使用 python 命令运行脚本:
python ~/project/my_function.py
你应该会看到以下输出:
(x: int, y: int) -> int
这个输出表示 add_numbers 函数的签名。它显示该函数接受两个参数 x 和 y,这两个参数都应为整数,并且该函数返回一个整数。
理解函数签名有助于你正确使用函数并避免常见错误。在接下来的步骤中,你将进一步了解如何使用 inspect 模块从函数签名中提取详细信息。
使用 inspect.signature()
在上一步中,你学习了如何使用 inspect.signature() 获取函数的签名。在这一步中,你将深入了解如何使用签名对象来提取有关函数参数的更详细信息。
inspect.signature() 函数返回一个 Signature 对象,该对象具有几个用于检查函数参数的有用属性和方法。让我们修改 my_function.py 脚本来探索这些特性。
使用 VS Code 编辑器打开你 ~/project 目录中的 my_function.py 文件,并按如下方式修改它:
## filename: ~/project/my_function.py
import inspect
def add_numbers(x: int, y: int = 10) -> int:
"""This function adds two numbers and returns the result."""
return x + y
sig = inspect.signature(add_numbers)
for param in sig.parameters.values():
print(f"Parameter Name: {param.name}")
print(f"Parameter Default: {param.default}")
print(f"Parameter Annotation: {param.annotation}")
print(f"Parameter Kind: {param.kind}")
print("-" * 20)
在这个修改后的脚本中:
- 我们为
y参数添加了默认值10(y: int = 10)。 - 我们遍历
Signature对象的parameters属性,它是一个由Parameter对象组成的有序字典。 - 对于每个
Parameter对象,我们打印其name、default、annotation和kind属性。
现在,使用 python 命令运行脚本:
python ~/project/my_function.py
你应该会看到以下输出:
Parameter Name: x
Parameter Default: <class 'inspect._empty'>
Parameter Annotation: <class 'int'>
Parameter Kind: POSITIONAL_OR_KEYWORD
--------------------
Parameter Name: y
Parameter Default: 10
Parameter Annotation: <class 'int'>
Parameter Kind: POSITIONAL_OR_KEYWORD
--------------------
让我们来详细分析一下输出:
- 参数名称:参数的名称(
x和y)。 - 参数默认值:参数的默认值。如果参数没有默认值,这里将显示为
inspect._empty。 - 参数注解:参数的类型注解(例如
<class 'int'>)。 - 参数类型:参数的类型,可以是
POSITIONAL_OR_KEYWORD、VAR_POSITIONAL、VAR_KEYWORD、KEYWORD_ONLY或POSITIONAL_ONLY。在这种情况下,x和y都是POSITIONAL_OR_KEYWORD,这意味着它们既可以作为位置参数传递,也可以作为关键字参数传递。
通过使用 inspect.signature(),你可以更深入地了解函数的参数及其属性。这些信息对于编写能够正确与函数交互的代码以及有效地记录你的代码非常有价值。
使用 try-except 测试参数传递
在这一步中,你将学习如何使用 try-except 块来处理向函数传递参数时可能出现的错误。当处理用户输入或外部数据时,这一点尤为重要,因为数据类型或格式可能并非函数所预期的。
让我们修改 my_function.py 脚本,使用 try-except 来进行错误处理。我们将尝试使用无效参数调用 add_numbers 函数,并捕获由此产生的 TypeError。
使用 VS Code 编辑器打开你 ~/project 目录中的 my_function.py 文件,并按如下方式修改它:
## filename: ~/project/my_function.py
import inspect
def add_numbers(x: int, y: int = 10) -> int:
"""This function adds two numbers and returns the result."""
return x + y
try:
result = add_numbers("hello", 5)
print(f"Result: {result}")
except TypeError as e:
print(f"Error: {e}")
try:
result = add_numbers(5, "world")
print(f"Result: {result}")
except TypeError as e:
print(f"Error: {e}")
try:
result = add_numbers(5, 5)
print(f"Result: {result}")
except TypeError as e:
print(f"Error: {e}")
在这个修改后的脚本中:
- 我们将对
add_numbers的调用包装在try-except块中。 - 我们尝试以字符串作为第一个参数、整数作为第二个参数来调用
add_numbers。 - 我们尝试以整数作为第一个参数、字符串作为第二个参数来调用
add_numbers。 - 我们尝试以两个整数作为参数来调用
add_numbers。 - 如果发生
TypeError(当我们传递字符串而非整数时会发生这种情况),我们捕获该异常并打印错误消息。 - 如果没有发生
TypeError,我们打印函数调用的结果。
现在,使用 python 命令运行脚本:
python ~/project/my_function.py
你应该会看到以下输出:
Error: unsupported operand type(s) for +: 'str' and 'int'
Error: unsupported operand type(s) for +: 'int' and 'str'
Result: 10
这个输出展示了如何使用 try-except 块来优雅地处理向函数传递无效参数时出现的错误。前两次对 add_numbers 的调用导致了 TypeError 异常,这些异常被 except 块捕获并处理。第三次使用两个整数调用 add_numbers 成功执行,并打印了结果。
使用 try-except 块是编写健壮可靠代码的最佳实践。它允许你预见潜在的错误,并以防止程序崩溃的方式处理它们。
总结
在本次实验中,你学习了 Python 中的函数签名,以及它们如何提供有关函数预期参数和返回值的信息。理解函数签名对于编写简洁且可维护的代码至关重要。
本实验展示了如何使用 inspect 模块,特别是 inspect.signature() 函数,来检索和检查 Python 函数的签名。你创建了一个带有类型提示的简单函数,然后使用 inspect.signature() 将函数的签名打印到控制台,从而揭示预期的参数类型和返回类型。



