如何在 Python 函数中传递可选参数?

2025年1月5日 | 阅读6分钟

引言

Python 函数中以可选属性形式存在的参数提供了一定的灵活性,并可用于函数调用。它们允许定义可以调用任意数量参数的函数。这些函数将具有未传递参数的内置定义。反思运算符如何作为表达式工作可以帮助提高代码的可读性和可维护性。在本指南中,我们将介绍在 Python 中向函数传递可选参数的不同方法以及最佳方法。

函数参数基础

函数参数是指在调用函数时传递给函数的一些输入。参数可分为两类:

位置参数和关键字参数布局。

位置参数在函数签名中指定,并在其调用中作为位置参数设置。例如:

输出

 
Hello, Alice! How are you?

此示例显示 Alice 的名字用作 name 参数,"How are you?"用作 message 参数,这取决于其参数出现的顺序。

可变参数在函数头中通过位置表示,而关键字参数在函数调用中通过其名称突出显示。它们支持函数参数传递更加灵活,尤其适用于参数较多的函数。例如:

输出

 
Hello, Bob! How are you?

在此,message 参数是可选的,"How are you?"是默认值。否则,如果未明确指定,则将使用默认值。

1. 可选参数

可选参数可以有默认参数的别名,它们在函数签名中具有预先指定的值。在函数调用中,由于参数已指定默认值,因此不需要为其赋值。因此,不需要在函数调用中为其赋值。

然而,在函数调用期间,通过向函数传递特定值,可以实现覆盖的可能性。

让我们通过一个实际示例更仔细地了解可选参数的工作原理:

输出

 
Hello, Alice! How are you?
Hello, Bob! Goodbye

说明

第一次函数调用仅传递 message 参数,而 message 参数使用默认值 "How are you?"。对于第二次函数调用,已传递两个参数,值为 name="David" 和 message="How are you today?",从而覆盖了默认的 "How are you?"。

2. 使用 'None' 作为默认参数

在 Python 中,如果需要,可以使用 'None' 作为可选参数的占位符。当默认值需要是可变的(例如)或者需要区分显式传递的 None 与默认行为时,此技术非常适用。

请看以下示例

输出

 
[1]
[2]
[4, 3]

说明

在这种情况下,函数接受 val 作为参数,另一个是名为 lst 的可选参数,其默认值为 None。在函数体内部,如果 'list 参数' 是 None,则将使用 'list 参数' 创建一个空列表,而不是 None。通过这种模型,列表会在函数调用后重复创建,除非明确要求。

3. 使用 *args 和 **kwargs

Python 中处理参数的函数还具有可选的 *kwargs 和 **args。*args 通过传递所需数量的固定参数来为函数提供位置参数,而 **kwargs 允许您将可变数量的参数作为关键字参数传递。

以下是如何使用 *args 和 **kwargs 来处理可选参数:

输出

 
Hello, Alice, Bob! How are you?
Hello, Alice, Bob! Goodbye
Hello! Goodbye

说明

  • greet 函数旨在允许任意数量的姓名和一个可选的自定义消息,并使用可变参数列表(长度可变)。
  • *args 将任意数量的位置参数组合在一起,并将它们放入一个元组中。
  • **kwargs 将 kwargs 转换为一个包含关键字参数的字典。
  • 该函数在 kwargs 中检查 'message',如果不存在则使用默认值。
  • "您想让我发送的消息是什么?默认消息是“您好吗?”"
  • 如果 args 不为空,它会在名字前面添加逗号,从而从个性化名字创建多重问候。
  • 示例调用和输出:
  • Greet("Alice", "Bob") 然后回复“你好,Alice,Bob!”。此外,您必须想出像“您好吗?”这样的默认消息。
  • Say_hi("Alice", "Bob", text="再见!") 回复“你好,Alice,Bob!”。再见",但作为消息,我们为我们心爱的人创建一个特殊的问候。
  • Greet(message="再见") 结果是“你好!”再见",当我们不定义名字但指定特定消息时。

最佳实践

  1. 默认参数值:您绝对应该为参数使用不可变对象作为默认值。基本对象包括 None、True、False,以及整数和字符串。因此,使用列表或字典等可变默认值不会出现这种情况,因为这些对象在多个函数调用之间共享。
  2. 显式优于隐式:使用变量名可以更轻松地了解每个参数在函数中的作用。后者可以通过为参数和函数本身使用描述性名称来实现。然而,对于 **kwargs 的使用,请确保相关关键字已得到充分记录或通过周围代码上下文明确说明。
  3. 文档:全面记录此函数的重要性、其输入、输出以及处理的异常。事实上,当您使用 *args 和 **kwargs 时,这变得最为关键,因为上述功能可能会导致对预期输入产生混淆,从而使整个过程完全偏离正轨。
  4. 虽然 *args 和 **kwargs 提供了灵活性,但过度使用它们会使函数接口变得不集中,并且理解它们将非常困难。在绝对必要时使用它们,例如在与第三方 API 集成或处理具有自身属性的子类方法时。
  5. 使用类型提示:在 Python 中,PEP 484(PEP 代表 Python Enhancement Proposal)中的类型提示在很大程度上实现了这一目的。这样编写的代码就更容易理解和维护。即使对于 *args 和 **kwargs,类型提示也可以阐明参数的预期类型,例如:def func(*args: def area_circle(radius: float, color: str = "purple") -> None
  6. 妥善处理 None 默认值:请注意,如果可能为列表、字典或其他可变对象的参数设置为 None,则有必要在函数体内进行检查,并在需要时分配一个新对象。这有助于精确地识别和预防它们。函数应该只做一件事,并且应该简短明了。参数的数量,无论是否可选,都会使函数变得复杂,因此使用起来会很麻烦。提供重写函数或使用类的示例,这些示例可以封装具有更多参数的复杂行为。
  7. 测试:对代码进行充分的功能测试,尤其是在函数具有可选参数和可变参数列表时。测试应涵盖所有预期的数据类型、边界情况以及函数不接受任何参数或关键字参数与预期参数不匹配时的情况。

结论

本指南演示了在 Python 中为函数提供可选参数的各种方法和建议的可用性。可选参数是使函数调用灵活且现代化的功能,让开发人员有机会创建更具表现力和可重用性的代码。如果使用得当并遵循最佳实践,可选参数有助于提高 Python 代码的可读性和可维护性。