Python函数传参方法分类汇总

python传入参数的类型分为:值传递和引用传递,其区别在于前者拷贝了与实参值相同的副本在函数内操作,因此对函数外原值没有影响,后者则地址和原来参数相同,函数内更改后函数外的值随之更改
传不可变对象,如数值,字符串,元组,为值传递
传可变对象,如列表,集合,字典,为引用传递
下面的传参方法均以传不可变对象为例

大部分教程把传参方式分为4种:
必备参数(位置参数)
关键字参数
默认参数
不定长参数(动态参数、非固定传参)
https://www.runoob.com/python/python-functions.html
https://www.cnblogs.com/hls-code/p/15392638.html
这样分成的几类,虽然是对基本传参方式的覆盖,但是并不是一个划分,容易引起混乱,比如默认参数和不定长参数在传入时也可以用关键字参数
可是依据我个人来看,分成三类比较合理:
定长参数
默认参数
不定长参数

然后继续进行划分
定长参数分为位置参数和关键字参数
默认参数也可以分为位置参数和关键字参数
不定长参数分为传入后打包为元组,字典这两类

下面说一些实例:
定长参数:

def fun(name,id):
    print(name,id)

fun("tjq",12)#全部是位置参数
fun(name="tjq",id=12)#全部是关键字参数
fun(id=12,name="tjq")#关键字参数顺序可以不同
fun("tjq",id=12)
#fun(name="tjq",12)#会报错,因为位置参数要在关键字参数前面

运行结果


tjq 12
tjq 12
tjq 12
tjq 12

默认参数:

def fun(name,id,year=4):
    print(name,id+1,year-1)

fun("tjq",12)#可以缺省默认参数
fun(name="tjq",id=12)
fun(id=12,name="tjq")
fun("tjq",id=12)
#fun(name="tjq",12)#会报错,因为位置参数要在关键字参数前面
fun("tjq",12,5)
fun(name="tjq",id=12,year=5)
#fun(name="tjq",id=12,5)#会报错,因为位置参数要在关键字参数前面
fun(id=12,name="tjq",year=5)
fun("tjq",12,year=5)

结果:

tjq 13 3
tjq 13 3
tjq 13 3
tjq 13 3
tjq 13 4
tjq 13 4
tjq 13 4
tjq 13 4

Process finished with exit code 0

不定长参数:
传入后打包为元组的方式,是按位置传参


def fun(name,id,year=4,*subgrade,school="NEU",age):
    print(name,id+1,year,subgrade,school,age)
    sum=0
    for i in subgrade:
        sum+=i
    return sum
print(fun("tjq",12,age=20))
print(fun("tjq",12,90,95,96,age=20))#此时默认参数按照位置被赋值为90
#print(fun("tjq",12,4,90,95,96,20))#会报错,因为可变参数(*)之后的参数必须指定参数名【即关键字传参】,否则就会被归到可变参数之中TypeError: fun() missing 1 required keyword-only argument: 'age'
#fun(name="tjq",id=12,90,95,96)#会报错,因为可变参数前面不能指定参数名 SyntaxError: positional argument follows keyword argument
print(fun("tjq",12,4,90,95,96,age=20,school='neu'))
print(fun("tjq",*(12,4,90,95,96),school='neu',age=20,))#*()元组解包,解包后和正常按照位置传参无异
tjq 13 4 () NEU 20
0
tjq 13 90 (95, 96) NEU 20
191
tjq 13 4 (90, 95, 96) neu 20
281
tjq 13 4 (90, 95, 96) neu 20
281

传入后打包为字典的方式,是按关键字传参



def fun(name,id,year=4,*subgrade,school="NEU",age,**optgrade):
    print(name,id+1,year,subgrade,school,age,optgrade)
    sum=0
    for i in subgrade:
        sum+=i
    return sum

print(fun("tjq",12,4,90,95,96,age=20,school='neu'))
print(fun("tjq",12,4,90,95,96,age=20,school='neu',math=95,English=94,Computer=96))
print(fun("tjq",12,4,90,95,96,age=20,school='neu',**{"math":95,"English":94,"Computer":96}))#**{}为字典解包,解包后效果等价于关键字传参
print(fun("tjq",12,4,90,95,96,math=95,English=94,Computer=96,school='neu',age=20))
#print(fun("tjq",12,4,90,95,96,age=20,school='neu',math=95,English=94,Computer=96,age=20))#用**接收不定长参数时不能和前面有重名参数,SyntaxError: keyword argument repeated: age
#

结果:

tjq 13 4 (90, 95, 96) neu 20 {}
281
tjq 13 4 (90, 95, 96) neu 20 {'math': 95, 'English': 94, 'Computer': 96}
281
tjq 13 4 (90, 95, 96) neu 20 {'math': 95, 'English': 94, 'Computer': 96}
281
tjq 13 4 (90, 95, 96) neu 20 {'math': 95, 'English': 94, 'Computer': 96}
281

其中,这三种定义方式:

def fun2(**optgrade,age=20):
def fun2(**optgrade,age):
def fun2(**optgrade,*age):

会报错

 def fun2(**optgrade,age=20):
                        ^
SyntaxError: invalid syntax

因为默认形参、位置形参不能放在这种** 形式参数后面,在传参时解释器不知道** 在哪里截止

在四种方式混合使用时,要遵守以下规则:
1.位置参数要在关键字参数前面
2.可变参数(*)之后的参数必须指定参数名【即关键字传参】
3.可变参数(**)要放在最后

推断出赋值过程为:
先按位置传参
然后把剩下没有args=val形式的实参打包成元组传入
然后args=val形式的实参先传给可对应的args形参
无法对应的打包成字典传入

以上为个人总结,可能会有一定偏差,请评论区指出!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值