当我们在编写函数时,会定义一些占位符,这些占位符就是参数,参数是函数定义中用于接收外部传递值的占位符,这个会帮助我们在函数被调用时接收外部传递的值。在Python当中,有各种各样类型的参数,主要有位置参数、默认参数、关键字参数、可变位置参数、可变关键字参数以及强制关键字参数。
位置参数
位置参数(Positional Arguments)是最常见的参数类型,也是默认的参数类型,大家平时写的函数基本上都是位置参数,算是非常好理解的。它们按照在函数定义中的顺序进行传递,并且在函数调用时必须按照顺序提供。
代码语言:javascript复制def greet(name, message):
print(message, name)
greet("Alittle", "Hello") # 输出: Hello Alittle
默认参数
默认参数(Default arguments)就是这些参数在函数定义时就有默认值,当函数被调用时,如果没有为该参数提供特定的值,那么就会使用默认值作为参数的值。通过给参数设置默认值,可以让函数在某些情况下更加灵活和方便使用。如果调用函数时没有提供该参数的值,函数就会使用默认值,否则将使用传递给参数的值。
代码语言:javascript复制def greet(name, message="Hello"):
print(message, name)
# 使用默认参数调用函数
greet("Alittle") # 输出: Hello Alittle
# 传递特定的参数值调用函数
greet("Kobe", "Hi") # 输出: Hi Kobe
需要注意的是,在Python中,默认参数是按照从左到右的顺序依次设置的,如果你想给第一个参数设置默认值,必须确保它位于后面的参数之前。也就是说给倒数第二个参数设置默认值,必须先给倒数第一个参数设置默认值。
代码语言:javascript复制def greet(name="Iverson", message):
print(message, name)
# 由于第一个参数设置了默认值,可以仅传递第二个参数
greet("Kobe")
以上例子运行的时候会报错:
代码语言:javascript复制 File "D:Program FilesJetBrainsPycharmProjectshello.py", line 33
def greet(name="Iverson", message):
^^^^^^^
SyntaxError: non-default argument follows default argument
尝试给第一个参数设置默认值时会出现语法错误。这是因为在定义函数时,默认参数只能放在非默认参数的后面。 所以如果我们想给第一个参数设置默认值,可以考虑使用关键字参数的方式传递参数值,或者两者参数换一下位置就可以了。
关键字参数
关键字参数(Keyword Arguments)是一种在函数调用时使用参数名称来指定参数值的方式。使用关键字参数可以使函数调用更加清晰和易读,特别是当函数有多个参数且它们具有相同的数据类型或默认值时。
就比如上面默认参数的那个例子:
代码语言:javascript复制def greet(name, message):
print(message, name)
# 使用关键字参数调用函数
greet(name="Iverson", message="Hello") # 输出: Hello Iverson
greet(message="Hi", name="Kobe") # 输出: Hi Kobe
在上述示例中,我们在函数调用时通过参数名称指定了参数值。这样一来,不仅可以准确传递参数,还可以使函数调用的意图更加清晰和易懂。即使函数定义中第一个参数设置了默认值,运行也不会报错。
所以使用关键字参数可以显式地指定参数名称,可以避免因参数顺序错误而导致的错误。并且只给关心的参数传递值,而忽略其他参数。在函数调用时提供了更好的可读性和可维护性。
可变位置参数
可变位置参数(Variable Length Positional Arguments)是一种允许函数接受任意数量的位置参数的特性。在函数定义时,使用星号(*)作为前缀来表示可变位置参数。它会将所有传入的位置参数打包成一个元组(tuple)。在函数定义时,我们可以在参数列表中使用*args来接收这些参数。
代码语言:javascript复制def calculate_sum(*numbers):
total = 0
for num in numbers:
total = num
return total
print(calculate_sum(1, 2, 3)) # 输出: 6
print(calculate_sum(4, 5, 6, 7, 8)) # 输出: 30
另外需要注意的是,可变位置参数要放在其他参数的后面。也就是说,函数定义中先定义的参数,会按照位置顺序读取实参的数值,而可变位置参数将会读取剩下的所有实参。比如你要像这样子写就会报错:
代码语言:javascript复制def calculate_sum(*numbers, message):
total = 0
for num in numbers:
total = num
return message, total
result = calculate_sum(1, 2, 3, "Sum=")
print(result)
运行的话会报以下错误
代码语言:javascript复制Traceback (most recent call last):
File "D:Program FilesJetBrainsPycharmProjectshello.py", line 40, in <module>
result = calculate_sum( 1, 2, 3, "Sum=")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: calculate_sum() missing 1 required keyword-only argument: 'message'
可变关键字参数
可变关键字参数(Variable Keyword Arguments)是指在函数定义时,使用**前缀来接收任意数量的关键字参数。有点类似key,value的格式,它会将所有传入的关键字参数打包成一个字典(dict),在函数内部可以使用键值对的方式进行访问。
代码语言:javascript复制def calculate_sum(*args, **kwargs):
total = sum(args)
for key, value in kwargs.items():
total = value
return total
result = calculate_sum(1, 2, 3, num1=4, num2=5)
print(result) # 输出: 15
在这个示例中,calculate_sum
函数接受可变位置参数args
和可变关键字参数kwargs
。可变位置参数args
用于接收任意数量的位置参数,而可变关键字参数kwargs
用于接收任意数量的关键字参数。在函数内部,我们首先使用calculate_sum
函数对可变位置参数args
进行求和。然后,我们遍历可变关键字参数kwargs
,将关键字参数的值累加到总和中。
可变关键字参数提供了一种灵活的方式来处理不确定数量的关键字参数,并为函数提供更大的扩展性和适应性。
强制关键字参数
强制关键字参数(Keyword-only arguments)是在3.1版本之后引入的,指在函数定义时,使用*后缀来限制函数调用时必须使用关键字参数进行传递,而不允许使用位置参数。
代码语言:javascript复制def greet(*, name, message): # 使用分隔符“*”,表示后面的参数必须使用关键字传递
print(message, name)
greet(name="Alittle", message="Hi") # 关键字参数传递方式
greet("Kobe", "Hi")
第一处调用greet
没有问题,但是第二处调用greet
就会抛出异常,报错
Traceback (most recent call last):
File "D:Program FilesJetBrainsPycharmProjectshello.py", line 39, in <module>
message = greet("Kobe", "Hi")
^^^^^^^^^^^^^^^^^^^
TypeError: greet() takes 0 positional arguments but 2 were given
通过使用强制关键字参数,我们可以明确传递参数的意义,避免参数位置的混乱,并提高代码的可读性和健壮性。