文章目录
- 前言
- 一、了解形式参数和实际参数
- 1. 通过作用理解
- 2. 通过一个比喻来理解形式参数和实际参数
- 二、位置参数
- 1. 数量必须与定义时一致
- 2. 位置必须与定义时一致
- 三、关键字参数
- 四、为参数设置默认值
- 五、可变参数
- 1. *parameter
- 2. **parameter
- 总结
前言
在调用函数时,大多数情况下,主调函数和被调函数之间有数据传递关系,这就是有参数的函数形式。函数参数的作用是传递数据给函数使用,函数利用接收的数据进行具体的操作处理。函数参数在定义函数时放在函数名称的后面的一对小括号中,对于初学者来说,函数参数一般是难点。接下来针对参数展开详细介绍。
一、了解形式参数和实际参数
在使用参数时,经常会用到形式参数和实际参数,二者都叫做参数,它们的区别将先通过形式参数与实际参数的作用来进行讲解,再通过一个比喻和实例进行深入探讨。
1. 通过作用理解
形式参数和实际参数在作用上的区别如下:
- 形式参数:在定义函数时,函数名后面括号中的参数为 “形式参数”。
- 实际参数:在调用一个函数时,函数名后面括号中的参数为 “实际参数”,也就是将函数的调用者提供给函数的参数称为实际参数。通过下图可以更好的理解。
根据实际参数的类型不同,可以分为将实际参数的值传递给形式参数和将实际参数的引用传递给形式参数两种情况。其中,当实际参数为不可变对象时,进行值传递;当实际参数为可变对象时,进行的是引用传递。实际上,值传递和引用传递的基本区别就是,进行值传递后,改变形式参数的值,实际参数的值不变;而进行引用传递后,改变形式参数的值,实际参数的值也一同改变。
例如,定义一个名称为 function 的函数,然后为 function() 函数传递一个字符串类型的变量作为参数(代表值传递),并在函数调用前后分别输出该字符串变量,再为 function() 函数传递一个列表类型的变量作为参数(代表引用传递),并在函数调用前后分别输出该列表。代码如下:
# 定义函数
def sentence(place):
print('原值:', place)
place += place
# 调用函数
print('==========值传递==========')
a = '丽江'
print('函数调用前:', a)
sentence(a) # 采用不可变对象 —— 字符串
print('函数调用后:', a)
print('==========引用传递==========')
list1 = ['昆明', '长沙', '西安']
print('函数调用前:', list1)
sentence(list1) # 采用可变对象 —— 列表
print('函数调用后:', list1)
上面代码的执行结果如下:
==========值传递==========
函数调用前: 丽江
原值: 丽江
函数调用后: 丽江
==========引用传递==========
函数调用前: ['昆明', '长沙', '西安']
原值: ['昆明', '长沙', '西安']
函数调用后: ['昆明', '长沙', '西安', '昆明', '长沙', '西安']
从上面的执行结果可以看出,在进行值传递时,改变形式参数的值后,实际参数的值不改变;在进行引用传递时,改变形式参数的值后,实际参数的值也发生改变。
2. 通过一个比喻来理解形式参数和实际参数
函数定义时参数列表中的参数就是形式参数,而函数调用时传递进来的参数就是实际参数。就像剧本选主角一样,剧本的角色相当于形式参数,而演角色的演员就相当于实际参数。
二、位置参数
位置参数也称必备参数,是必须按照正确的顺序传到函数中,即调用时的数量和位置必须和定义时是一样的。
1. 数量必须与定义时一致
在调用函数时,指定的实际参数的数量必须与形式参数的数量一致,否则将抛出 TypeError 异常,提示缺少必要的位置参数。如下图代码所示:
2. 位置必须与定义时一致
在调用函数时,指定的实际参数的位置必须与形式参数的位置一致,否则将产生以下两种结果。
- 抛出 TypeError 异常。抛出异常的情况主要是因为实际参数的类型与形式参数的类型不一致,并且在函数中,这两种类型还不能正常转换。 例如下图代码所示:
- 产生的结果与预期不符。在调用函数时,如果指定的实际参数与形式参数的位置不一致,但是它们的数据类型一致,那么就不会抛出异常,而是产生结果与预期不符的问题。例如下图代码所示:
说明:由于调用函数时,传递的实际参数的位置与形式参数的位置不一致时,并不会总是抛出异常,所以在调用函数时一定要确定好位置,否则会产生 Bug,还不容易被发现。
三、关键字参数
关键字参数是指使用形式参数的名字来确定输入的参数值。通过该方式指定实际参数时,不再需要与形式参数的位置完全一致。只要将参数名写正确即可。这样可以避免用户需要牢记参数位置的麻烦,使得函数的调用和参数传递更加灵活方便。比如下图代码所示:
四、为参数设置默认值
调用函数时,如果漏掉忘了指定某个参数则将会抛出异常,为了解决这个问题,我们可以为参数设置默认值,即在定义函数时,直接指定形式参数的默认值。这样,当没有传入参数时,则直接使用定义函数时设置的默认值。定义带有默认值参数的语法格式如下:
def functionname(..., [parameter1 = defaultvalue1]):
[functionbody]
参数说明:
- functionname:函数名称,在调用函数时使用。函数名称的命名应遵循标识符命名规则,如果有多个单词,每个单词用下划线_连接。
- parameter1 = defaultvalue1:可选参数,用于指定向函数中传递的参数,并且为该参数设置默认值为 defaultvalue1。
- functionbody:可选参数,用于指定函数体,即该函数被调用后,要执行的功能代码。
代码示例如下图所示:
说明:在传参时,如果没有指定某个参数值,则使用形式参数中该参数的默认值;如果指定了参数值,则会覆盖默认值,使用指定的参数值;比如下图代码所示。
注意:在定义函数时,指定默认的形式参数必须在所有参数的最后,否则将产生语法错误。比如下图所示。
说明:定义函数时,为形式参数设置默认值要牢记一点:默认参数必须指向不可变对象。
五、可变参数
在Python中,还可以定义可变参数。可变参数也称为不定长参数,即传入函数中的实际参数可以是任意多个。定义可变参数时,主要有两种形式:一种是 *parameter,另一种是 **parameter。
1. *parameter
这种形式表示接收任意多个实际参数并将其放到一个元组中。例如,定义一个函数,让其可以接收任意多个实际参数,代码如下图所示:
如果想要使用一个已经存在的列表作为函数的可变参数,可以在列表的名称前加 “ * ”。例如下图代码所示:
2. **parameter
这种形式表示接收任意多个类似于关键字参数一样显式赋值的实际参数,并将其放到一个字典中。例如,定义一个函数,让其可以接收任意多个显式赋值的实际参数,代码如下图所示:
如果想要使用一个已经存在的字典作为函数的可变参数,可以在字典的名称前加 “ ** ”。例如下图代码所示:
总结
参数是学习函数必须要精通的重要一环。对初学者来说,默认值参数是易错点;可变参数是难点;每个参数都是要掌握的重点。