京公网安备 11010802034615号
经营许可证编号:京B2-20210330
Python函数参数类型*、**的区别
刚开始学习python,python相对于java确实要简洁易用得多。内存回收类似hotspot的可达性分析, 不可变对象也如同java得Integer类型,with函数类似新版本C++的特性,总体来说理解起来比较轻松。只是函数部分参数的"*"与"**",闭包等问题,着实令人迷糊了一把,弄清概念后写下此文记录下来,也希望本文能够帮助其他初学者。
所以本文是一篇学习笔记,着重于使用的细节和理解上,首先分别介绍了函数各种参数类型在调用和声明时的区别,及其在混用时需要注意的一些细节,之后讲了闭包相关的内容。如果有不对的地方欢迎指正。
函数参数不带“*”,"*" 与 "**"的区别
理解这个问题得关键在于要分开理解调用和声明语法中3者得区别.
函数调用区别
1. 不同类型的参数简述
#这里先说明python函数调用得语法为:

举个例子来说明这4种调用方式得区别:
#这种调用方式的函数处理等价于
a,b,c,d,e = 1,2,3,4,5
print a,b,c,d,e
#-------------------------------
#keyword_args方式
>>> test(a=1,b=3,c=4,d=2,e=1)
1 3 4 2 1
#这种处理方式得函数处理等价于
a=1
b=3
c=4
d=2
e=1
print a,b,c,d,e
#-------------------------------
#*tuple_grp_nonkw_args方式
>>> x = 1,2,3,4,5
>>> test(*x)
1 2 3 4 5
#这种方式函数处理等价于
#---------------------------------
#**dict_grp_kw_args方式
>>> y
{'a': 1, 'c': 6, 'b': 2, 'e': 1, 'd': 1}
>>> test(**y)
1 2 6 1 1
#这种函数处理方式等价于
a = y['a']
b = y['b']
... #c,d,e不再赘述
print a,b,c,d,e
2. 不同类型参数混用需要注意的一些细节
接下来说明不同参数类型混用的情况,要理解不同参数混用得语法需要理解以下几方面内容.
首先要明白,函数调用使用参数类型必须严格按照顺序,不能随意调换顺序,否则会报错. 如 (a=1,2,3,4,5)会引发错误,; (*x,2,3)也会被当成非法.
其次,函数对不同方式处理的顺序也是按照上述的类型顺序.因为#keyword_args方式和**dict_grp_kw_args方式对参数一一指定,所以无所谓顺序.所以只需要考虑顺序赋值(positional_args)和列表赋值(*tuple_grp_nonkw_args)的顺序.因此,可以简单理解为只有#positional_args方式,#*tuple_grp_nonkw_args方式有逻辑先后顺序的.
最后,参数是不允许多次赋值的.
举个例子说明,顺序赋值(positional_args)和列表赋值(*tuple_grp_nonkw_args)的逻辑先后关系:
#错误的例子
>>> test(1,b=2,*x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: test() got multiple values for keyword argument 'b'
#正确的例子1,处理等价于
a,b = 1,2 #顺序参数
c,d,e = x #列表参数
print a,b,c,d,e
#正确的例子2,处理等价于
a = 1 #顺序参数
e = 2 #关键字参数
b,c,d = x #列表参数
#错误的例子,处理等价于
a = 1 #顺序参数
b = 2 #关键字参数
b,c,d = x #列表参数
#这里由于b多次赋值导致异常,可见只有顺序参数和列表参数存在罗辑先后关系
函数声明区别
理解了函数调用中不同类型参数得区别之后,再来理解函数声明中不同参数得区别就简单很多了.
1. 函数声明中的参数类型说明
函数声明只有3种类型, arg, *arg , **arg 他们得作用和函数调用刚好相反.
调用时*tuple_grp_nonkw_args将列表转换为顺序参数,而声明中的*arg的作用是将顺序赋值(positional_args)转换为列表.
调用时**dict_grp_kw_args将字典转换为关键字参数,而声明中**arg则反过来将关键字参数(keyword_args)转换为字典.
特别提醒:*arg 和 **arg可以为空值.
以下举例说明上述规则:
#----------------------------
#*arg将顺positional_args转换为列表
>>> test2(1,2,[1,2],{'a':1,'b':2})
1 (2, [1, 2], {'a': 1, 'b': 2}) {}
#该处理等价于
a = 1 #arg参数处理
b = 2,[1,2],{'a':1,'b':2} #*arg参数处理
c = dict() #**arg参数处理
print a,b,c
#-----------------------------
#**arg将keyword_args转换为字典
>>> test2(1,2,3,d={1:2,3:4}, c=12, b=1)
1 (2, 3) {'c': 12, 'b': 1, 'd': {1: 2, 3: 4}}
#该处理等价于
a = 1 #arg参数处理
b= 2,3 #*arg参数处理
#**arg参数处理
c = dict()
c['d'] = {1:2, 3:4}
c['c'] = 12
c['b'] = 1
print a,b,c
2. 处理顺序问题
函数总是先处理arg类型参数,再处理*arg和**arg类型的参数. 因为*arg和**arg针对的调用参数类型不同,所以不需要考虑他们得顺序.
闭包
python的函数,原本只能访问两个区域的变量:全局,和局部(函数上下文).
实际上,函数本身也是一个对象,也有自己的作用域. 闭包通过函数与引用集合的组合,使得函数可以在它被定义的区域之外执行.
这个集合可以通过func_closure来获取这个引用集合.
这与python处理全局变量得方式一样,只不过全局变量将引用集合存储在__globals__字段中.func_closure是一个存储cell类型的元组,每个cell存储一个上下文变量.
另外,旧版本得python的内部函数不能在其他作用域使用的原因,并不是因为每个作用域的变量严格相互隔离,而是脱离原本的作用域后,函数失去了原本上下文的引用。需要注意的是,闭包存储的上下文信息一样是浅拷贝,所以传递给内部函数的可变对象仍然会被其他拥有该对象引用得变量修改.
举个例子:
>>> def foo(x,y):
... def bar():
... print x,y
... return bar
...
#查看func_closure的引用信息
>>> a = [1,2]
>>> b = foo(a,0)
>>> b.func_closure[0].cell_contents
[1, 2]
>>> b.func_closure[1].cell_contents
0
>>> b()
[1, 2] 0
#可变对象仍然能被修改
>>> a.append(3)
>>> b.func_closure[0].cell_contents
[1, 2, 3]
>>> b()
[1, 2, 3] 0
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
在构建前向神经网络(Feedforward Neural Network,简称 FNN)时,“隐藏层数目设多少?每个隐藏层该放多少个神经元?” 是每个 ...
2025-10-29这个问题切中了 Excel 用户的常见困惑 —— 将 “数据可视化工具” 与 “数据挖掘算法” 的功能边界混淆。核心结论是:Excel 透 ...
2025-10-29在 CDA(Certified Data Analyst)数据分析师的工作中,“多组数据差异验证” 是高频需求 —— 例如 “3 家门店的销售额是否有显 ...
2025-10-29在数据分析中,“正态分布” 是许多统计方法(如 t 检验、方差分析、线性回归)的核心假设 —— 数据符合正态分布时,统计检验的 ...
2025-10-28箱线图(Box Plot)作为展示数据分布的核心统计图表,能直观呈现数据的中位数、四分位数、离散程度与异常值,是质量控制、实验分 ...
2025-10-28在 CDA(Certified Data Analyst)数据分析师的工作中,“分类变量关联分析” 是高频需求 —— 例如 “用户性别是否影响支付方式 ...
2025-10-28在数据可视化领域,单一图表往往难以承载多维度信息 —— 力导向图擅长展现节点间的关联结构与空间分布,却无法直观呈现 “流量 ...
2025-10-27这个问题问到了 Tableau 中两个核心行级函数的经典组合,理解它能帮你快速实现 “相对位置占比” 的分析需求。“index ()/size ( ...
2025-10-27对 CDA(Certified Data Analyst)数据分析师而言,“假设检验” 绝非 “套用统计公式的机械操作”,而是 “将模糊的业务猜想转 ...
2025-10-27在数字化运营中,“凭感觉做决策” 早已成为过去式 —— 运营指标作为业务增长的 “晴雨表” 与 “导航仪”,直接决定了运营动作 ...
2025-10-24在卷积神经网络(CNN)的训练中,“卷积层(Conv)后是否添加归一化(如 BN、LN)和激活函数(如 ReLU、GELU)” 是每个开发者都 ...
2025-10-24在数据决策链条中,“统计分析” 是挖掘数据规律的核心,“可视化” 是呈现规律的桥梁 ——CDA(Certified Data Analyst)数据分 ...
2025-10-24在 “神经网络与卡尔曼滤波融合” 的理论基础上,Python 凭借其丰富的科学计算库(NumPy、FilterPy)、深度学习框架(PyTorch、T ...
2025-10-23在工业控制、自动驾驶、机器人导航、气象预测等领域,“状态估计” 是核心任务 —— 即从含噪声的观测数据中,精准推断系统的真 ...
2025-10-23在数据分析全流程中,“数据清洗” 恰似烹饪前的食材处理:若食材(数据)腐烂变质、混杂异物(脏数据),即便拥有精湛的烹饪技 ...
2025-10-23在人工智能领域,“大模型” 已成为近年来的热点标签:从参数超 1750 亿的 GPT-3,到万亿级参数的 PaLM,再到多模态大模型 GPT-4 ...
2025-10-22在 MySQL 数据库的日常运维与开发中,“更新数据是否会影响读数据” 是一个高频疑问。这个问题的答案并非简单的 “是” 或 “否 ...
2025-10-22在企业数据分析中,“数据孤岛” 是制约分析深度的核心瓶颈 —— 用户数据散落在注册系统、APP 日志、客服记录中,订单数据分散 ...
2025-10-22在神经网络设计中,“隐藏层个数” 是决定模型能力的关键参数 —— 太少会导致 “欠拟合”(模型无法捕捉复杂数据规律,如用单隐 ...
2025-10-21在特征工程流程中,“单变量筛选” 是承上启下的关键步骤 —— 它通过分析单个特征与目标变量的关联强度,剔除无意义、冗余的特 ...
2025-10-21