python函数参数详解

liftword2个月前 (03-17)技术文章7

python有两种传参的方式,位置参数关键字参数

位置参数

位置参数是基于它们的位置或顺序传递给函数的参数。这些参数是必需的,并且必须按照与函数参数列表匹配的正确顺序提供。

以下是一个示例:

def greet(name, message):
    print(f"{message}, {name}!")

greet("John", "Hello")  # 输出:Hello, John!
 # 错误,位置参数是必须的
 greet('John')

关键字参数

关键字参数是指在函数调用时使用参数名称来传递参数的一种方式。与位置参数不同,关键字参数使用参数名称和参数值的键值对来传递参数。在函数定义时,可以指定关键字参数及其默认值,如果在函数调用时没有指定某个关键字参数的值,则会使用其默认值。

以下是一个使用关键字参数的例子:

def greet(name, message="Hello"):
    print(message + ", " + name)

greet('Byte Dance')
greet('Hello', 'Byte Dance')
greet(name="Byte Dance")
greet(message="Hi", name="Byte Dance")
greet(name="Byte Dance", message="Hi") #关键字参数顺序可变

在这个例子中,greet 函数有两个参数,name 和 message。message 是一个关键字参数,它有一个默认值 "Hello"。在函数调用时,我们可以通过参数名称来指定参数值。第一个函数调用中,我们只指定了 name 参数的值,使用了默认的 message 参数值。在第二个函数调用中,我们同时指定了 name 和 message 参数的值,它们的顺序没有影响。

注意,所有默认参数值的形参必须定义在没有默认值的形参,否则会报错,如下方示例:

#错误,a是有默认值的,b是没有默认值
def foo(a=1, b):
    pass

函数调用时的传参方式

默认情况下,调用函数时参数既可以用位置参数的形式传入,也可以用关键字参数形式传参,位置参数必须在关键字参数前, 一旦使用了关键字参数则关键字后面的所有参数必须也用关键是参数的形式传参。如下方的例子:

def standard_arg(arg):
    print(arg)

standard_arg(1)
standard_arg(arg=1)
def kw_after_pos(a, b, c):
    print(a, b, c)

kw_after_pos(1,2,3)
kw_after_pos(a=1, b=2, c=3)
kw_after_pos(1, b=2, c=3)
#错误,关键字参数后不能再使用位置参数
kw_after_pos(1, b=2, 3)

有些情况下,有些参数是只能用位置参数关键字参数的一种来传参。

含有特殊形参 / 或 *

在定义函数时有2个特别的形参, / *

/: 如果 / 出现在了形参中,则在调用函数时,/ 前的所有参数必须以位置参数的形式传入。

*: 如果 * 出现在了形参中,则在调用函数时,* 后的所有参数必须以关键字参数的形式传入。

/ 和 * 中间的参数可以以说位置参数也可以是关键字参数。如下图所示:

  1. 如果定义函数时,用了 / 这个形参, 则 / 的参数只能以位置参数的方式传
def pos_only_arg(arg, /):
    print(arg)

pos_only_arg(1)
# 报错
pos_only_arg(arg=1)
  1. 如果定义函数时,用了 * 这个形参, 则 * 的参数只能以关键字参数的方式传参
def kwd_only_arg(*, arg):
    print(arg)

kwd_only_arg(arg=1)
#报错,必须以关键字参数的方式传参
kwd_only_arg(1)
  1. 既有 / 又有 * 的情况, standard参数在中间,既可以以位置参数的形式,也可以以关键字参数的形式传参:
def combined_example(pos_only, /, standard, *, kwd_only):
    print(pos_only, standard, kwd_only)

combined_example(1, 2, kwd_only=3)
combined_example(1, standard=2, kwd_only=3)

任意个数的参数

如果在定义参数时,使用了类似 *name这种形式的形参,则所有多余的位置参数会被打包成tuple赋值给name,通常可变参数(*name)是最后一个形参,如果不是,则所有出现在*name后面的参数必须以关键字参数的形式传参。如下方例子:

def arbitrary_args(a, b, *c):
    print(f'a:{a}\nb:{b}\nc:{c}')
    print('type(c):', type(c))

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

同样的,还有个 **name 的形参,如果定义时使用了这个形参, 则所有多余的关键字参数会被打包成dict赋值给name,如下方例子:

def arbitrary_args(a, b, *c, **d):
    print(f'a:{a}\nb:{b}\nc:{c}\nd:{d}')
    print('type(d):', type(d))

arbitrary_args(1, 2, 3, 4, 5, 6, 7)
arbitrary_args(1, 2, 3, 4, 5, 6, 7, kw1=1, kw2=2)

调用函数时,用*和**解包参数

* 运算符可以用来解包列表参数,比如内置的range()函数需要单独的start和stop参数,我们有一个列表变量args=[3, 6],可以使用*运算符对参数进行解包然后传给range:

args = [3, 6]
list(range(*args)) # 等价于 list(range(3, 6))

对比 list(range(3, 6)):

** 运算符可以用来解包字典参数提供关键字参数:

def parrot(voltage, state='a stiff', action='voom'):
	print("-- This parrot wouldn't", action, end=' ')
	print("if you put", voltage, "volts through it.", end=' ')
	print("E's", state, "!")

d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
parrot(**d) # 等价与 parrot(voltage='four million', state="bleedin' demised", action='VOOM')

对比parrot(voltage='four million', state="bleedin' demised", action='VOOM'):

相关文章

Python基础 - 函数的位置参数、关键字参数、默认参数

在 Python 中,调用函数可以按照函数的位置传递参数(位置参数),也可以按照参数的名称传递参数(关键字参数),函数的参数还可以在定义的时候指定默认值(默认参数)。此外,Python 还支持可变参数...

python之函数的参数详解

参数传递:1.不可变数据类型:数字number(含int、float、bool、complex)、字符串string、元组tuple。当不可变数据类型被当作函数的参数,传递的是值,函数体内改变值时实际...

【Python程序开发系列】一文总结Python函数参数和传递方式

这是我的第217篇原创文章。一、引言函数,在定义的时候,可以有参数的,也可以没有参数。从函数定义的角度来看,参数可以分为两种:必选参数:调用函数时必须要指定的参数,在定义时没有等号可选参数:也叫默认参...

Python教程(25)——Python中参数类型详解

当我们在编写函数时,会定义一些占位符,这些占位符就是参数,参数是函数定义中用于接收外部传递值的占位符,这个会帮助我们在函数被调用时接收外部传递的值。在Python当中,有各种各样类型的参数,主要有位置...

【Python机器学习系列】使用Hyperopt搜索随机森林模型最优超参数

这是我的第342篇原创文章。一、引言Hyperopt是一个强大的python库,用于超参数优化,由jamesbergstra开发。Hyperopt使用贝叶斯优化的形式进行参数调整,允许你为给定模型获得...