Python 传递参数与参数类型,前面大刀阔斧地说了关于函数定义和使用,在这一节我们谈论一些细节但是重要的问题一一参数。对于在一开始就设定了必要参数的函数来说,我们是通过打出函数的名称并向括号中传递参数实现对函数的调用(call),即只要把参数放进函数的括号中即可,就像是这样:
fahrenheit_converter(35)
fahrenheit_converter(15)
fahrenheit_converter(0)
fahrenheit_converter(-3)
事实上,传递参数的方式有两种:
现在从似乎被我们遗忘的梯形的数学公式开始入手,首先还是创建函数。
我们把函数的名称定为 trapezoid_area
,也就是梯形面积,设定参数为 base_up
(上底),base_down
(下底),height
(高),每一个都用英文输入法的逗号隔开。梯形的面积需要知道这三个值才能求得,因此对于构造梯形面积的函数来说,这三个参数缺一不可。
def trapezoid_area(base_up, base_down, height):
return 1/2 * (base_up + base_down) * height
接下来我们开始调用函数。
trapezoid_area(1,2,3)
不难看出,填入的参数 1
,2
,3
分别对应着参数 base_up
,base_down
和 height
。 这种传入参数的方式被称作为位置参数。
接着是第二种传入方式:
trapezoid_area(base_up=1, base_down=2, height=3)
更直观地,在调用函数的时候,我们将每个参数名称后面赋予一个我们想要传入的值。这种以名称作为一一对应的参数传入方式被称作是关键词参数。
想一想去餐厅预约与就餐的流程:找到你预约的座位一般是用你留下的姓名,你就是一个参数,你会被按照姓名的方式传入你预定的座位,这个就是关键词参数传入;接下来是上菜,菜品按照你的座位号的方式来传入你的桌子,而这就相当于是位置传入参数。
也许你现在想不太明白这种传入方式有何作用,没有关系,后面我们会和其他知识一并进行讲解,到那时你就会对参数的传入方式有更高层次的认识。
避免混乱的最好方法就是先制造混乱,我们试着解决一个更复杂的问题,按照下面几种方式调用函数并打印结果:
trapezoid_area(height=3, base_down=2, base_up=1) # RIGHT!
trapezoid_area(height=3, base_down=2, 1) # WRONG!
trapezoid_area(base_up=1, base_down=2, 3) # RIGHT!
trapezoid_area(1, 2, height=3) # RIGHT!
- 第一行的函数参数按照反序传入,因为是关键词参数,所以并不影响函数正常运作;
- 第二行的函数参数反序传入,但是到了第三个却变成了位置参数,遗憾的是这种方式是错误的语法,因为如果按照位置来传入,最后一个应该是参数 height 的位置。 但是前面 height 已经按照名称传入了值3,所以是冲突的。
- 第三行的函数参数正序传入,前两个是以关键词的方式传入,最后一个以位置参数传入,这个函数是可以正常运行的;
- 第四行的函数参数正序传入,前两个是以位置的方式传入,最后一个以关键词参数传入,这个函数是可以正常运行的。
注:正确运行的结果应该是4.5,也就是这个梯形的面积。
我们现在给一组变量赋值,然后再调用函数:
base_up = 1
base_down = 2
height = 3
trapezoid_area(height, base_down, base_up)
然而这次函数调用的结果应该是2.5,为什么?
如果你有这样的困惑,说明你已经被参数的命名和变量的命名搞晕,我们来把这两者区分清晰。首先,我们在定义函数的时候会定义参数的名称,其作用是使用函数时指导我们传入什么参数,它们从哪里来,是什么类型等,提供与使用函数相关的上下文。下面这段代码也许能够帮助你摆脱函数来自参数名称的困扰:
def flashlight (battery1, battery2):
return 'Light!'
我们定义一个叫做手电筒(flashlight)的函数,它需要两个参数 battery1
和 battery2
意为电池。这时候你去商店买电池,买回了两节600毫安时的南孚电池,于是:
nanfu1 = 600
nanfu2 = 600
flashlight(nanfu1, nanfu2)
看明白了吗?南孚是电池的一种,是可以让手电筒发光的东西,将南孚电池放入就意味着我们放入了手电筒所需的电池,换句话说,nanfu1
,nanfu2
是变量,同时也是满足能够传入的函数的 flashlight 函数的参数,传入后就代替了原有的 battery1
和 battery2
且传入方式仍旧是位置参数传入。battery1
和 battery2
只是形式上的的占位符,表达的意思是函数所需的参数应该是和电池即 battery 有关的变量或者是对象。
你看到的这个魔法就是我们将要提到的神奇的默认参数。默认参数是可选的,这意味着即使你上来不给它传入什么东西,函数还是可以正常运作。
你只需要这样输入代码:
def trapezoid_area(base_up, base_down, height=3):
return 1/2 * (base_up + base_down) * height
给一个参数设定默认值非常简单,我们只需要在定义参数的时候给参数赋值即可。这个也许跟传入参数的方式有点像,但是千万别记混了!这可是在定义的时候做的事情!这样一来,我们只需要传入两个参数就可以正常进行了:
trapezoid_area(1, 2)
你肯定会疑惑,如果设定默认值的话,那么所有梯形的高岂不是都固定成3了啊? 然而并没有,默认值的理念就是让使用函数尽可能的简单、省力。正如同我们安装软件都会有默认目录,但是如果你又想安装在其他地方,你可以选择自定义修改。之前看到的 print 函数的小把戏也正是如此,print 的可选参数 sep(意为每个打印的结果以…分开)的默认值为‘ ’空格,但是我们将其重新传入‘/n’
也就是换行的意思,一句话说,也就是将每个打印的数以换行符号进行分割。下面我们来调用自己的参数:
trapezoid_area(1, 2, height=15)
只需要传入我们想要的值就可以了,就是这么简单。
默认值并非是你掌握参数使用的必要知识,却是能帮助我们节省时间的小技巧。在实际项目中也经常会看见这样:
requests.get(url, headers=header)
注:请求网站时 header,可填可不填
img.save(img_new, img_format, quality=100)
注:给图片加水印的时候,默认的水印质量是100