您的位置:

Python函数传参详解

一、位置参数

位置参数是指函数在定义时,按照顺序给形参赋值,调用函数时,按照相同的顺序提供实参,实参的值会赋值给形参。以下是一个简单的函数实例:

def greet(name, message):
    print("Hello, " + name + ". " + message)
    
greet("John", "Welcome to our website!")

以上实例中, name 和 message 就是位置参数。您可以按照顺序提供实参,即 "John" 和 "Welcome to our website!",这些值将依次赋值给 name 和 message 形参。该函数的输出结果是:

Hello, John. Welcome to our website!

可以看出,如果实参与形参的顺序不一致,函数将会出现错误,同时这种情况下不同的入参顺序会导致函数运行结果不同。

此外,在函数定义时,可以给形参设置默认值。在调用函数时,如果没有提供实参,则会使用默认值。这时,即使顺序有些不同,函数也会正确运行。以下是一个简单的实例:

def greet(name, message="Welcome to our website!"):
    print("Hello, " + name + ". " + message)
    
greet("John")
greet("Jack", "How was your weekend?")

以上实例中,message 被赋以默认值 "Welcome to our website!",如果在调用函数时不提供 message 的值,则使用默认值。在第一次调用 greet 时,我们仅提供了 name 的值,即 "John"。因此, message 采用了默认值。 在调用函数时,我们给出了两个实参,且顺序正确,输出结果分别为:

Hello, John. Welcome to our website!
Hello, Jack. How was your weekend?

二、关键字参数

关键字参数在函数调用时使用形如 key=value 的语法进行传递参数。这些参数会被包含在一个字典中。以下是一个简单的实例:

def greet(name, message):
    print("Hello, " + name + ". " + message)
    
greet(name="John", message="Welcome to our website!")

以上实例中, name 和 message 就是关键字参数。通过使用形如 key=value 的语法,可以在函数调用中标明实参是哪个形参,从而避免了顺序混淆而带来的误用问题。该函数的输出结果是:

Hello, John. Welcome to our website!

在函数定义中,可以为参数设置默认值。如果函数定义中存在某些已经设置了默认值的参数,我们可以仅传递未设置默认值的关键字参数。 注意,请不要再定义函数时使用可变的数据类型作为关键字参数的默认值,这会带来一些意想不到的问题。以下是一个例子:

def greet(name, message="Welcome to our website!"):
    print("Hello, " + name + ". " + message)
    
greet(name="Jack")
greet(name="John", message="How was your weekend?")

第一次调用函数我们仅传递了一个参数 name 而未传递 message,默认值被使用。第二次调用函数我们分别传递了 name 和 message,函数使用了传递给 message 的值,并打印出:

Hello, John. How was your weekend?

三、*args 和 **kwargs

*args 和 **kwargs 实际上是 Python 中的特殊语法,它们允许我们在函数定义时定义不定数量的参数。我们可以使用 *args 来传递不定数量的非关键字参数,使用 **kwargs 传递不定数量的关键字参数。以下是一个简单的实例:

def greet(*args, **kwargs):
    if len(args) > 0:
        for name in args:
            print("Hello, " + name)
    elif "name" in kwargs and "message" in kwargs:
        print("Hello, " + kwargs["name"] + ". " + kwargs["message"])
    else:
        print("Hello, Anonymous!")
        
greet("John", "Jack", "Robert")
greet(name="Mary", message="Nice to meet you!")
greet()

在以上示例中,我们定义了一个 greet 函数,其接受任何数量的非关键字参数和关键字参数。在函数主体中,我们检查 args 中是否有任何非关键字参数。 如果是这样,则我们打印出"Hello, "以及相应的名称。否则,我们检查 kwargs 字典中是否存在 "name" 和 "message" 键。如果存在,则我们打印出相应的信息。否则,我们打印出 "Hello, Anonymous!"。我们多次调用该函数,传递不同数量的参数及参数类型,可以看到输出结果为:

Hello, John
Hello, Jack
Hello, Robert
Hello, Mary. Nice to meet you!
Hello, Anonymous!

四、单个星号与双星号

单个星号和双星号有两种不同的用法:

第一种是在函数定义时使用它们来收集参数:

def sum(a, b, c):
    print(a + b + c)

my_numbers = [1, 2, 3]
sum(*my_numbers)

在以上实例中,我们定义了一个接受三个参数的 sum 函数,同时我们将 my_numbers 列表中的三个值传递给函数 sum。 这是通过使用星号运算符(*)来实现的。 在函数调用中,星号解包了列表,并将它们解释为单独的参数。这种方式非常适用于需要将一个预先存在的它们需要解构成单个参数的列表或元组作为参数的函数。 以上代码的输出结果是:

6

第二种用途,是用作函数调用时解包参数。 这使得 python 函数能够接受变长数量的位置参数和关键字参数。 此用法在在前面提到的 **kwargs 用法上起到补充作用,它们可以组合在一起一起使用。以下是一个简单的实例:

def greet(name, message):
    print("Hello, " + name + ". " + message)
    
params = {"name": "John", "message": "Welcome to our website!"}
greet(**params)

在以上示例中,我们定义了一个 greet 函数,它接受了两个关键字参数 name 和 message。我们通过传递一个字典对象给该函数来调用该函数。 这是在使用星号运算符(**)时可以做到的,它允许我们使用字典对象来提供函数的关键字参数。 以上代码的输出结果是:

Hello, John. Welcome to our website!

五、传递可变长度的参数

在 Python 中,可以定义一个可以接受不同数量参数的函数,无论是关键字参数还是位置参数。 以下是一些示例:

1、接受可变长度列表的函数:

def sum(*args):
    my_sum = 0
    for i in args:
        my_sum += i
    return my_sum

print(sum(1, 2, 3))

在以上示例中,我们定义了一个函数 sum,它接受任何数量的参数,并使用 args 变量来捕获这些参数。我们的函数代码遍历 args,将它们相加,并返回总和。 在调用函数 sum 时,我们传递了三个参数 1, 2 和 3 。 以上代码的输出结果是:

6

2、接受关键字参数的函数:

def optional_args(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")
        
optional_args(option1=1, option2=2, option3=3)

在以上示例中,我们定义了一个将接受关键字参数的函数 optional_args,它遍历 kwargs,并打印其中每对键值的值。在调用函数 optional_args 时,我们传递了三个关键字参数——option1 设为 1,option2 设为 2,option3 设为3. 以上代码的输出结果是:

option1: 1
option2: 2
option3: 3

六、总结

通过本文的讲解,我们了解了 Python 函数中传参的各种方式,包括位置参数、关键字参数、*args 和 **kwargs,以及单个星号与双星号与可变长度参数。对于不同的情境和需求,我们可以在定义、调用函数时选择不同的传参方式,以实现正确计算和更好的可读性。