函数的参数

Posted Leslie-x

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了函数的参数相关的知识,希望对你有一定的参考价值。

1.形参与实参

基本概念:

  形参,形式参数,指的是定义函数时,括号内定义的参数,是某种意义上的变量名

  实参,实际参数,指的是调用函数时,括号内传入的值,是某种意义上的变量值

注意点:

  实参和形参的绑定关系只有在函数调用时才会生效,调用结束后解除绑定,释放空间。调用函数,就是把实参赋值给形参的过程

2.位置参数

  位置即顺序,指的是从左到右的顺序依次定义的参数

2.1.位置形参
  定义函数时,按照位置顺序定义的形参
  def foo(x,y,z):
    print(x,y,z)
  foo(1,2) #程序报错
  foo(1,2,3,4)#程序报错
  foo(1,2,3)#程序运行正常
  从上面的程序运行结果,可以总结到位置形参的特性:
    #调用时必须为其传值,而且传入的值必须一个不多,一个不少

2.2.位置实参
  调用函数时,按照位置顺序定义传入的值
  位置实参特性:
    位置实参必须与形参一一对应

3.关键字参数

  在调用函数时,以key=value形式定义的实参,称为关键字实参,相当于指名道姓的为形参传值,即便是不按照顺序定义,仍然能为指定形参传值

 def foo(x,y,z):
    print(x,y,z)
 foo(x=1,y=2,z=3) 
 foo(x=1,z=2,y=3)
 foo(z=3,x=2,y=1)
#在以关键字参数为位置形参传值时,只要按照key=value的形式,就可以不用按照顺序
4.混合参数

   在调用函数时,传入的实参同时有位置实参和关键字实参

 def foo(x,y,z):
     print(x,y,z)
 # 位置实参必须翻到关键字实参的前面
 foo(1,2,z=3)  #正确
 foo(x=1,2,3) #错误
 # 必须遵循形参的规则
 foo(1,2,y=3)#正确
 foo(1,2,z=3)#错误
 # 不能为同一个形参重复传值
 foo(x=1,y=2,z=3)#正确
 foo(1,x=2,y=3,z=4)#错误
5.默认参数
  在定义阶段已经为某个形参赋值,那么该形参就被称为默认参数。可以传值也可以不传值,经常需要变的参数定义成位置形参,变化较小的参数定义成默认参数
def resgister(name,age,sex = "male"):
    print(name,age,sex)
#1:默认参数已有值,,可以传值也可以不用传值
resgister("egon",18)
resgister("alex",73,"female")
resgister("wxx",45)

#2:位置形参必须在默认参数的前面
def resgister(sex = "male",name,age):
    print(name,age,sex)
resgister("alex",73,"female")#程序报错
def resgister(name,age,sex = "male",): 
  print(name,age,sex)
resgister("alex",73,"female")#程序正常
#3:默认参数的值,只在定义阶段赋值一次,也就是说在定义阶段默认参数已经写死了
m =10
def foo(x,y=m):
    print(x,y)
m =100
foo(1)# 1 10

#4:默认参数的值应该设置成不可变类型
#默认参数的值是可变类型
def resgister(name,hobby,l = []):
    l.append(hobby)
    print(name,hobby,l)
#错误实例 resgister(
"egon","play")#egon play [‘play‘] resgister("alex","read")#alex read [‘play‘, ‘read‘] resgister("wxx","sleep")#wxx sleep [‘play‘, ‘read‘, ‘sleep‘]
#正确实例 resgister("egon","play",[]) #egon play [‘play‘] resgister("alex","read",[]) #alex read [‘read‘] resgister("wxx","sleep",[]) #wxx sleep [‘sleep‘] #把默认参数的值设置成不可变类型 def resgister(name,hobby,l = None): if l is None: l = [] l.append(hobby) print(name,hobby,l) resgister("egon","play") #egon play [‘play‘] resgister("alex","read") #alex read [‘read‘] resgister("wxx","sleep") #wxx sleep [‘sleep‘]
#对于经常需要变化的值,需要将对应的形参定义错位置形参,
#对于大多数情况值都一样的情况,需要将对应的形参定义成默认形参
6.可变长参数

  可变长指的是实参的个数不确定

  而实参有按位置的位置实参和按关键字的关键字实参两种形式,针对这两种形式的可变长,形参对于有两种解决方案来完整的存放他们分别是*args和**kwargs

    *args:可变长度的位置形参。

      *会将溢出的位置实参全部接收,然后保存成元组形式,赋值给args

    *kwargs:可变长度的关键字形参。

      **会将溢出的关键字参数全部接收,然后保存成字典形式,赋值给kwargs

    *args和*kwargs主要的功能都是有*和**完成,后面的argshe kwargs都只是变量名,是什么并不重要,但是约定俗成,也就如此了。

    *args是可变长的位置形参,所以也具有位置形参的一切特性,*后定义的参数必须被传值(默认参数除外),切必须以关键字形式传值

def foo(x, y, *args, a=1, b, **kwargs):
    print(x, y)
    print(args)
    print(a)
    print(b)
    print(kwargs)
#结果
1
2
(3, 4, 5)
1
3
{‘c‘: 4, ‘d‘: 5}
7.在实参中的*和**

   在上面的学习中,形参中的*和**把溢出的位置实参和关键字实参分别存成了元组和字典,那么在实参中*和**又是有什么功能呢?

实参加*,就把该实参的值打散成字符串
def foo(x,y,z):
    print(x,y,z)
foo(*[1,2,3])
#foo(*[123]) == foo(1,2,3) 实参加
**,就把该实参的值打散成关键字参数 def foo(x,y,z,**kwargs): print(x,y,z) print(kwargs) foo(1,2,3,**{"a":4,"b":5})
#foo(1,2,3,**{"a":4,"b":5}) == foo(1,2,3,a=4,b=5)

#打散的关键字实参和位置实参重复
def foo(x,y,z,**kwargs):
  print(x,y,z)
  print(kwargs)
foo(1,2,3,**{"x":4,"b":5})
#TypeError: foo() got multiple values for argument x

 

以上是关于函数的参数的主要内容,如果未能解决你的问题,请参考以下文章

Python函数

第四篇 函数

解决方案电影标题中缺少代码的片段,完成挑战更多[关闭]

VSCode自定义代码片段——声明函数

Swift 学习- 07 -- 函数

VSCode自定义代码片段8——声明函数