Python函数的参数传递及其原理分析
Python作为一门高级编程语言,函数是其中最核心的概念之一,是完成复杂功能的重要组成部分。即使其他程序设计语言与Python在函数定义、调用等方面有所不同,但函数的本质和定义思想都是相似的,那就是输入参数,进行运算或操作,输出结果。
另外,Python函数支持多种形式的参数,来满足不同需求的函数调用,比如默认参数、不定长参数、关键字参数等。各种参数类型,如何传递参数及其实现原理也是本文要探讨的内容。
一、函数参数
在Python中,函数参数包括:形式参数、实际参数。形参是定义函数时设定的参数,实参是函数调用时传递的参数。
Python的函数定义通常形如下:
def function_name(parameters):
function_body
return value
函数参数的完整定义格式: def Function_Name( arg1, arg2, ... argn):
其中arg1、arg2、…argn为参数列表,可以包括位于函数定义的任何位置,可以有零个或多个。也即,Python函数的参数又可区分为位置参数及关键字参数。下面说一下具体实现方法。
1.位置参数
定义方式:直接在括号中赋给形参参数,在调用时,该参数的值应该传递在函数的实参列表中,并且根据位置进行匹配与传递。
下面是一个位置参数的例子:
def runoob(a,b):
print("a=",a)
print("b=",b)
#这里函数runoob有两个形参a和b
runoob(1,2)
上面的代码,输出结果为:
a= 1 b= 2
2.默认参数
定义方式:给形参设置一个默认值,在函数调用时若没有传入其对应的实际参数,就会使用默认值,而不会出现TypeError 错误。
下面是一个默认参数的例子:
def default_arg(name, age=18):
print(name, age)
#调用时,可以有一个或两个参数
default_arg('Alice', 19)
default_arg('Tom')
上面代码输出结果为:
Alice 19 Tom 18
3.不定长参数
在Python中,提供了三种不定长参数的定义方式:*args, **kwargs和*非捕获引用。
a).*args
该参数定义为一个元组,用在函数传递不固定数量的非关键字参数时使用。注意,*args可以在args之后还可以有参数。例如:
def printargs(a, *args, b):
print(a)
for arg in args:
print(arg)
print(b)
#可以调用printargs函数如下
printargs('alice', 'bob', 'eve', b='Tom')
上面代码输出结果为:
alice bob eve Tom
b)**kwargs
该参数定义为一个字典,用在函数传递不固定数量的关键字参数时使用。注意,这里的**kwargs可以在kwargs之后,还可以有其他的参数。例如:
def example(a, x=1, y=2, **args):
print(a)
print(args)
#调用了example, 其中a是位置参数, x=1, y=2是关键字参数,*kwargs捕获之外的关键字参数
example(1, y=10, x=20, z=30, w=40)
上面代码输出结果为:
1
{'z': 30, 'w': 40}
c)*非捕获引用
这种定义方式使用一个*符号来引用其他参数,并可以在参考到以命名方式传递参数时使用。它的作用就是把一些指定的位置参数传递到接收过程的后序部分,这些位置参数能够在调用中按照顺序被传递。
这个符号通常在函数定义中的参数列表的末尾,这表明这个参数希望捕获之外的所有位置参数的引用。例如:
def add(a, b, *, c, d):
return a + b + c + d
#调用add函数,必须传递参数c和d,而非以位置参数传递
add(1, 2, c=3, d=4)
上面代码输出结果为:
10
二、参数传递
在Python中,参数可以按照引用传递。根据传递类型的不同,参数分为 不变对象(像数值、字符串、元组等) 和 可变对象(像字典、列表等)。
值类型变量和其对应形参进行按值传递,它们是在栈内存中被分配和释放的,这就是python pass by value(按值传递)。列表和字典在程序中是以引用方式传递的:当一个列表变量或字典变量被添加到形参列表中后,实参和形参变量将引用同一个列表或字典对象,这就是python pass by reference(按引用传递)。
下面的例子说明可变(引用)对象和不变(值)对象的参数传递情况。
def immutable_arg(a):
a += 2 # 注意这里的赋值是将变量重新赋值给了一个新的值地址,而不是修改一个原地址上的值
print(a)
def mutable_arg(a):
a.append(1)
print(a)
immutable_num = 10
immutable_arg(immutable_num) #输出12
print(immutable_num) #输出10
mutable_list = [1,2,3]
mutable_arg(mutable_list) #输出 [1, 2, 3, 1]
print(mutable_list) #输出 [1, 2, 3, 1]
三、总结
Python提供了三种参数传递方式,位置参数、默认参数和不定长参数。同时,Python也用按值传递和按引用传递两种方式来进行参数传递。通过本文的讲解,我们可以更好理解Python函数的参数传递及其原理分析。
