Python函数参数详解:形参与实参、位置与关键字、默认及可变参数

Oliver
Oliver
发布时间:2026-10-13 | 5人浏览过
原创

本文详细解析Python函数的参数分类与用法,涵盖形参与实参的定义与绑定机制、位置参数与关键字参数的混合调用规则、默认参数的赋值特性及可变类型陷阱,以及*和**处理可变长度实参的原理与实战技巧,帮助开发者掌握函数定义的规范与最佳实践。

Python函数参数概述

本文通过具体实例详细介绍Python函数中常见参数的分类及其使用方法,旨在为读者提供清晰的参考指南。

形参与实参的定义与绑定机制

1. 形参与实参的基本概念

形参(形式参数)是指

在定义函数时,括号内声明的参数,其本质是变量名。

实参(实际参数)是指在调用函数时传入的具体值,其本质是变量的具体数值。

例如在函数定义中,x和y即为形参。


def func(x,y):
  print(x)
  print(y)
func(20,30)
#20,30是实参

需要注意的是,实参的值与形参的变量名之间的绑定关系仅在函数调用期间生效;一旦函数调用结束,这种绑定关系会立即解除。

位置参数与关键字参数的使用规则

2. 函数的参数类型

位置参数是指按照从左到右的顺序依次定义的参数,其传递顺序必须与定义顺序一致。

3. 两种主要的参数形式:

(1)在定义函数时,按照位置顺序声明的形参被称为位置形参。


def foo(x,y,z):
  print(x,y,z)
foo(1,2,3)

注意:位置形参的特性要求调用函数时必须提供对应的值,既不能多传也不能少传。

(2)在调用函数时,按照位置顺序传入的实参被称为位置实参。

注意:位置实参会严格按照顺序与形参进行一一匹配。

4. 什么是关键字参数:

在调用函数时,采用key=value形式指定的实参被称为关键字参数。


def foo(x,y,z):
  print(x,y,z)
foo(5,9,3)
foo(y=8,x=1,z=4)

注意:这相当于明确指定为某个形参传值,因此即使不按照定义顺序,也能为特定的参数传递正确的值。

(1)在调用函数时,位置实参与关键字实参可以混合使用,但必须严格遵循形参的定义规则。


def foo(x,y,z):
  print(x,y,z)
foo(1,z=3,y=2) #这样写是正确的
foo(1,z=5) #这个没有遵循实参的规则,所以会报错

(2)严禁为同一个形参重复传递值。

(3)位置实参必须放置在关键字实参之前。


def foo(x,y,z):
  print(x,y,z)
foo(x=8,y=7,3) #里面的3就是位置实参,放在后面和中间都是不行的,必须要放在关键字实参的前面

正确的调用示例如下:


def foo(x,y,z):
  print(x,y,z)
foo(3,y=7,z=8)

默认参数的特性与注意事项

5. 默认参数

如果在函数定义阶段已经为某个形参赋予了初始值,则该形参被称为默认参数。

注意:

(1)由于定义阶段已有值,调用阶段可以选择性不传值。


def register(name,pasd,sex='yuan'):
  print(name,pasd,sex)
register('liuyuan',22,)
register('xiang',22)
register('xxx',80)

(2)位置形参必须定义在默认参数之前。


def func(y=1,x): #这是错误的,里面的x为位置形参,不能放在后面。
  pass

(3)默认参数的值仅在定义阶段赋值一次,即该值在定义时已固定,后续修改定义不会改变已绑定的默认值。


s=88
def foo(x,y=s):
  print(x,y)
s='555555555555555'
foo(1)
foo(1,22)

代码输出结果:

1 88 1 22

(4)重要原则:默认参数的值应设置为不可变类型,以避免潜在的副作用。


def register(name,hobby,l=None):
  if l is None:
    l=[]
  l.append(hobby)
  print(name,l)
register('liuyuan','play')
register('xiang','read')

上述代码的输出:

liuyuan ['play'] xiang ['read']

应用场景:对于频繁变化的值,应将其对应的形参定义为位置形参。

对于大多数情况下值保持一致的情况,应将其对应的形参定义为默认参数。

可变长度参数的处理与实战技巧

6. 处理可变长度参数的方法

什么是可变参数?

可变长度指的是参数的数量可以不固定,实参既包括按位置定义的实参,也包括按关键字定义的实参。

因此,可变长度实参指的是按照上述两种形式定义的实参数量可以不固定。

然而,无论实参如何变化,最终都需要向形参传递值。

因此,形参必须提供两种对应的解决方案,分别处理上述两种形式的可变长度实参。

(1)形参中包含*与**符号。

*符号会将溢出的位置实参全部接收,并以元组的形式保存,赋值给args变量。


def foo(x,y,z,*args):
  print(x,y,z)
  print(args)
foo(1,2,3,4,5,6,7,8,)

上述代码的输出:

1 2 3 (4, 5, 6, 7, 8)

**符号会将溢出的关键字实参全部接收,并以字典的形式保存,赋值给kwargs变量。


def foo(x,y,z,**kwargs):
  print(x,y,z)
  print(kwargs)
foo(x=1,y=2,z=3,a=5,b=6,c=7)

上述代码的输出:

1 2 3 {'a': 5, 'b': 6, 'c': 7}

注意:实参中也可以包含*与**符号。

一旦实参前带有*,该实参的值会被打散。


def foo(x,y,z,*args):
  print(x,y,z)
  print(args)
foo(1,2,3,*[4,5,6,7,8,9])
foo(1,2,3,*'h,e,l,l,o')

上述代码的输出:

1 2 3 (4, 5, 6, 7, 8, 9) 1 2 3 ('h', ',', 'e', ',', 'l', ',', 'l', ',', 'o')

一旦实参前带有**,该实参的值会被打散。


def foo(x,y,z,**kwargs):
  print(x,y,z)
  print(kwargs)

上述代码的输出:

1 8 3 {}

重点:组合使用技巧

这种用法在后续开发中将会频繁用到。


def index(name,age,gender):
  print('welcome %s %s %s' %(name,age,gender))
def wrapper(*args,**kwargs): #args=(1,2,3),kwargs={'x':1,'y':2,'z':3}
  index(*args,**kwargs) # index(*(1,2,3),**{'x':1,'y':2,'z':3}) # index(1,2,3,z=3,y=2,x=2)
wrapper('egon',age=18,gender='male')
wrapper('egon',18,gender='male')
wrapper('egon',18,'male')

上述代码的输出:

welcome yuan 18 male welcome xiang 18 male welcome abasida 0.6 male

对Python相关内容感兴趣的读者,可查看本站专题:《Python函数使用技巧总结》、《Python面向对象程序设计入门与进阶教程》、《Python数据结构与算法教程》、《Python字符串操作技巧汇总》、《Python编码操作技巧总结》及《Python入门与进阶经典教程》。

希望本文所述内容对大家学习Python程序设计有所帮助。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表