深入解析Python函数参数类型及其常见错误与解决方案

1 使用各种参数的陷阱

深入解析Python函数参数类型及其常见错误与解决方案

Python 功能强大、用途广泛的原因之一就是函数参数类型的多样化。方便的同时,也给用户带来了更多的约束规则。如果不理解这些规则,调用函数时可能会出现以下语法异常:

(1) 语法错误:位置参数跟随关键字参数

(2) TypeError: f() 缺少 1 个必需的仅关键字参数:'b'

(3) 语法错误:关键字参数重复

(4) 类型错误:f() 缺少 1 个必需的位置参数:'b'

(5) TypeError: f() 得到了意外的关键字参数 'a'

(6) 类型错误:f() 接受 0 个位置参数,但给出了 1 个

2 总结主要参数使用规则

位置参数

位置参数的定义:调用函数时,根据函数定义的参数位(形参)来传递参数。它是最常见的参数类型。

def f(a):
  return a
f(1) # 位置参数

位置参数不能缺失:

def f(a,b):
  pass
f(1) # TypeError: f() missing 1 required positional argument: 'b'

规则一:位置参数必须一一对应,缺一不可。

关键字参数

调用函数时,通过“key-value”方式传递函数参数的值,而不是根据位置传递函数参数的值。

def f(a):
  print(f'a:{a}')

在这个调用中,a是关键字参数:

f(a=1)

但下面的调用是不行的:

f(a=1,20.) # SyntaxError: positional argument follows keyword argument

规则 2:关键字参数必须位于位置参数的右侧

下面的调用也是不行的:

f(1,width=20.,width=30.) #SyntaxError: keyword argument repeated

规则3:不能向同一个形参重复传递值

默认参数

定义函数时,可以为形参提供默认值。对于有默认值的形式参数,如果调用函数时为参数传递了值,则使用传递的值,否则使用默认值。下面的b是默认参数:

def f(a,b=1):
  print(f'a:{a}, b:{b}')

规则4:无论是函数定义还是调用,默认参数的定义都应该在位置参数的右侧。

定义时只赋值一次;默认参数通常应定义为不可变类型

可变位置参数

定义如下的参数a是一个可变位置参数:

def f(*a):
  print(a)

调用方法:

f(1) #打印结果为元组:(1,)
f(1,2,3) #打印结果:(1, 2, 3)

但是,它不能这样调用:

f(a=1) # TypeError: f() got an unexpected keyword argument 'a'

可变关键字参数

下面的a是可变关键字参数:

def f(**a):
  print(a)

调用方法:

f(a=1) #打印结果为字典:{'a': 1}
f(a=1,b=2,width=3) #打印结果:{'a': 1, 'b': 2, 'width': 3}

但是,它不能这样调用:

f(1) TypeError: f() takes 0 positional arguments but 1 was given

3 五种参数的使用示例

今天我举一个python5参数使用的例子:位置参数、关键字参数、默认参数、可变位置或关键字参数。

def f(a,*b,c=10,**d):
  print(f'a:{a},b:{b},c:{c},d:{d}')

默认参数c不能跟在可变关键字参数d后面。

呼叫 f:

In [10]: f(1,2,5,width=10,height=20)
a:1,b:(2, 5),c:10,d:{'width': 10, 'height': 20}

可变位置参数b解析为实参后的元组(2,5); c 获取默认值 10; d 被解析为字典。

再次调用 f:

In [11]: f(a=1,c=12)
a:1,b:(),c:12,d:{}

当传入a=1时,a为关键字参数,b和d不传入值,c传入12而不是默认值。

注意观察参数a,它可以是f(1)或f(a=1)。它的可读性比第一个更好。推荐使用f(a=1)。如果要强制f(a=1),需要在前面加一个星号:

def f(*,a,*b):
  print(f'a:{a},b:{b}')

这时候调用f(1)就会报错:TypeError: f() Takes 0 Positional Argument but 1 was Give

只有f(a=1)才可以。

说明前面的*起作用了,就变成只能传入关键字参数了,那么如何检查这个参数的类型呢?在 python 的检查模块的帮助下:

In [22]: for name,val in signature(f).parameters.items():
    ...:     print(name,val.kind)
    ...:
a KEYWORD_ONLY
b VAR_KEYWORD

可以看到参数a的类型为KEYWORD_ONLY,只是一个关键字参数。

然而,如果 f 定义为:

def f(a,*b):
  print(f'a:{a},b:{b}')

查看参数类型:

In [24]: for name,val in signature(f).parameters.items():
    ...:     print(name,val.kind)
    ...:
a POSITIONAL_OR_KEYWORD
b VAR_POSITIONAL

可以看到参数a既可以是位置参数也可以是关键字参数。

你可能想看:
« 上一篇
下一篇 »

相关推荐

python爬虫教程PDF,Python爬虫书PDF

2026年09月02日

31阅读

外国教程python,python编程教学视频

2026年09月02日

25阅读

python简明教程沈洁元,python详细基础教程

2026年09月02日

21阅读

python库包教程,python 包

2026年09月02日

27阅读

python教程大全集,python教程600集

2026年09月02日

26阅读

python入门教程完整版,python零基础入门全套教程视频

2026年09月02日

22阅读