理解 Python 编程中 *args 与 **kwargs 的妙用

2024-03-31 10:20

本文主要是介绍理解 Python 编程中 *args 与 **kwargs 的妙用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、形式参数与实际参数
  • 二、*args 与 **kwargs
  • 三、总结

🍉 CSDN 叶庭云https://yetingyun.blog.csdn.net/


在 Python 编程中,*args**kwargs两种用于函数定义时处理可变数量的参数的机制。它们分别用于处理位置参数*args)和关键字参数**kwargs)。这两个机制提高了函数的灵活性和可重用性,允许开发者编写更加通用和灵活的代码。


一、形式参数与实际参数

在 Python 编程中,理解形参(形式参数)和实参(实际参数)的概念对于掌握函数的定义和调用至关重要。下面我将详细解释这两个概念,并通过一个具体的例子来展示它们在实际编程中的应用。

形参(形式参数)

形参是在函数定义时使用的参数名。它们仅仅是标识符,用于在函数体内部引用传递给函数的值。形参没有具体的值,它们的值由函数调用时传递的实参决定。可以将形参视为函数内部使用的变量名,这些变量名将在函数调用时被赋予具体的值

实参(实际参数)

实参是在函数调用时提供给函数的具体值或变量。这些值或变量将替换函数定义中的形参,以便在函数体内进行操作。实参可以是常量、变量或者表达式等,其值在函数调用时确定,并传递给对应的形参。

形参和实参在函数定义和调用中的作用和区别

  • 作用

    • 形参:定义了函数可以接收数据的 “占位符”,允许函数根据传入的不同实参执行相应的操作。

    • 实参:向函数提供了执行操作所需的具体数据或信息。

  • 区别

    • 定义位置:形参出现在函数定义中,而实参出现在函数调用中。

    • 数据类型:形参没有具体的数据类型,它们获得类型是通过接收到的实参决定的;实参则有具体的数据类型。

    • 作用范围:形参只在函数内部有效,它们是局部变量;实参可以是全局变量、局部变量或表达式等。

下面通过一个简单的例子来说明如何在实际编程中使用形参和实参:

# 定义一个函数,计算两个数的和
# 这里 x 和 y 是形式参数(形参)
def add(x, y):result = x + yreturn result# 调用上面定义的 add 函数
# 这里 5 和 3 是实际参数(实参)
sum = add(5, 3)print("The sum is:", sum)

在这个例子中:

  • add 函数定义了两个形式参数(xy),它们在函数被调用时会接收相应的实际参数。

  • 当我们调用 add(5, 3) 时,53 是实际参数(实参),它们被传递给 add 函数,并替换了形式参数 xy 的位置。

  • 函数内部使用这些传入的值(即实际参数)进行计算,并返回结果。

通过这个例子,我们可以看到形式参数和实际参数如何配合工作,使得我们能够编写灵活且可重复使用的代码。


二、*args 与 **kwargs

*args 的用途和工作原理:

  • 实参位置参数是指那些在函数调用时按照顺序直接传递的参数,这些参数不需要指定形参名。例如,在函数调用 func(a, b, 1) 中,a、b 和 1 都是位置参数。

  • 用途*args 用于在函数定义中处理那些数量不确定的位置参数。这意味着,通过使用 *args,你可以传递任意数量的位置参数给函数。

  • 工作原理:在函数内部,args 实际上是一个元组,它包含了所有传递给函数的位置参数。单个星号(*)是以新元组形式打包实参中所有的位置参数并将新元组赋值给星号后的变量 args,即收集位置参数。

如何使用 *args:

def my_function(*args):for arg in args:print(arg)my_function(1, 2, 3, 4)     # 输出:1 2 3 4

**kwargs 的用途和工作原理:

  • 实参关键字参数则是指在函数调用时通过指定形参名来传递的参数。这些参数在传递时必须包含形参名和对应的值。例如,在函数调用 func(a=1, b=2) 中,a=1 和 b=2 都是关键字参数。

  • 用途**kwargs 用于在函数定义中处理那些数量不确定的关键字参数。这意味着,通过使用 **kwargs,你可以传递任意数量的关键字参数给函数。

  • 工作原理:在函数内部,kwargs 实际上是一个字典,它包含了所有传递给函数的关键字参数。双星号(**)是以新字典形式打包实参中的所有关键字参数并将新字典赋值给双星号后的变量 kwargs,即收集关键字参数。

如何使用 **kwargs:

def my_function(**kwargs):for key, value in kwargs.items():print(f"{key}: {value}")my_function(name="John", age=30)     # 输出:name: John age: 30

利用 *args 和 **kwargs 提高代码灵活性和可重用性:

  • 组合使用:在同一个函数中同时使用 *args**kwargs 来允许接收任意数量的位置参数和关键字参数。

  • 函数装饰器:在编写装饰器时,经常会使用 *args**kwargs 来确保装饰器对于接收可变数量的参数的函数是通用的。

  • 继承与多态:在类方法中使用 *args**kwargs 可以方便地调用父类方法,无论父类方法定义了多少参数。

示例:组合使用 *args 和 **kwargs

def my_function(*args, **kwargs):for arg in args:print(arg)for key, value in kwargs.items():print(f"{key}: {value}")my_function(1, 2, name="John", age=30)

一些注意事项:

  • 使用 *args**kwargs 可以增加函数的灵活性,允许传递任意数量的位置或关键字参数。

  • 在函数定义中,*args 必须位于 **kwargs 之前,即位置参数必须位于关键字参数之前

  • 当与其他具有默认值的参数一起使用时,请确保将默认值参数放在 *args**kwargs 前面,即默认值参数需放在位置和关键字参数前面

  • 虽然 *args**kwargs 提供了极大的灵活性,但过度使用它们可能会使代码难以阅读和维护。因此,在清楚需要处理可变数量的参数时才考虑使用它们。


三、总结

在 Python 编程里,我们可以用一些特殊的符号来帮助我们处理函数的参数。这些符号有单个星号 * 和双星号 **

  1. 如果在一个函数的形式参数(就是函数定义时括号里的参数)前面加上一个星号,比如 *args,那就意味着你可以传入很多个没有指定名字的参数,这些参数会被打包成一个元组(就像一个包裹里装了很多东西),然后这个元组会被赋值给星号后面的那个变量名(args)。同样的,如果用两个星号,比如 **kwargs,就可以传入很多带名字的参数,它们会被打包成一个字典(就像一个有很多小抽屉的柜子,每个抽屉都贴着名字),然后这个字典会赋值给双星号后面的变量名(kwargs)。

  2. 当你调用一个函数的时候,如果你前面加星号,比如 *sequence,那就是把一个序列(比如列表、元组或字符串)里面的每个元素都拿出来,作为独立的参数传给函数。如果用两个星号,比如 **dict,就是把一个字典里的每个键值对都拿出来,作为带名字的参数传给函数。

  3. 如果你不确定要传给函数多少参数,或者你有一个序列(比如列表或元组)或者字典,并且你想把它们的内容作为参数传给函数,你可以在函数定义时使用星号和双星号来接收这些参数。

  4. 当你直接传递一个列表或字典给一个函数时,如果函数内部有修改操作,那么原始的列表或字典数据会被改变。这是因为列表和字典是可变类型,当你直接传递它们时,实际上是传递了它们在内存中的地址。函数可以通过这个地址来修改原始的列表或字典数据。当你用星号或双星号把一个列表或字典传给函数时,即使在函数里面对这些参数进行了修改,原来的列表或字典是不会改变的。这就像是你把家里的东西清单给了别人,即使别人在清单上画了勾或改了东西的顺序,你家里的东西还是那样,没有变。

通过合理利用 *args**kwargs,你可以编写出既灵活又易于维护的 Python 代码。


📚️ 相关链接:

  • Python 3.5 的解包操作符

  • Python 解包操作符 —— python 打包解包

  • Python —— 一文搞懂参数 args,kwargs

这篇关于理解 Python 编程中 *args 与 **kwargs 的妙用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/864100

相关文章

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

poj 3050 dfs + set的妙用

题意: 给一个5x5的矩阵,求由多少个由连续6个元素组成的不一样的字符的个数。 解析: dfs + set去重搞定。 代码: #include <iostream>#include <cstdio>#include <set>#include <cstdlib>#include <algorithm>#include <cstring>#include <cm

nudepy,一个有趣的 Python 库!

更多资料获取 📚 个人网站:ipengtao.com 大家好,今天为大家分享一个有趣的 Python 库 - nudepy。 Github地址:https://github.com/hhatto/nude.py 在图像处理和计算机视觉应用中,检测图像中的不适当内容(例如裸露图像)是一个重要的任务。nudepy 是一个基于 Python 的库,专门用于检测图像中的不适当内容。该

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝