第十一天学Python:函数(2):变化的参数

吾日三省吾身:预习了吗?学习了吗?复习了吗?日子一天天过去,老师们的网课讲得越来越顺,难度也在不断提高。与以往不同,这两天听课发现,稍微神游一会再听课就有些困难了:(
在这里插入图片描述

在昨天的内容函数(1).里大概介绍了一下函数的基本定义方法以及调用模块的几种方式,今天就接着昨天的内容,讲一讲当参数会发生变化时,自定义函数应当注意的问题。
直奔主题:

多个参数输入

昨天程序里大多是只有一个参数的函数,不需要考虑其它问题。当我们需要多参数时,有以下几种传递办法可选

位置参数

位置参数,就是在传递参数值的时候,必须和函数定义的参数一一对应,否则传递会发生误传甚至报错。
例如下面这个有两个参数的函数:

def price(name,cost):
	print('商品名称:%s,价格:%d'%(name,cost))
>>> price('Mate30',4999)	#正确输入
商品名称:Mate30,价格:4999

>>> price(4999,'Mate30')	#错误输入
TypeError: %d format: a number is required, not str

然鹅据说这种传参是最常用的方法之一。
这种固定形式传递的方法,要求我们对参数足够熟悉,才能避免输错(用help啊)

关键字参数

为了避免发生刚才的问题,就有了关键字参数:
依然是price函数

def price(name,cost):
	print('商品名称:%s,价格:%d'%(name,cost))

为了避免输错,在输入参数的时候,我们可以用 指定参数名=值 的方法。
这里直接反着输入试一下:

>>> price(cost=4999,name='Mate30')
商品名称:Mate30,价格:4999

在参数比较少的时候,我们也可以只指定一个参数:

>>> price('Mate30',cost=4999)
商品名称:Mate30,价格:4999

但是,只能是以“左边不指定,右边指定”的 方式,如果反过来:

>>> price(name='Mate30'4999)
SyntaxError: positional argument follows keyword argument
>>> price(cost=4999,'Mate30')
SyntaxError: positional argument follows keyword argument

这是说关键字参数不正确的意思

默认值

默认值就是在定义函数的时候直接让参数=一个值,当没有给这个参数传值的时候,这个参数就会用它自己的默认值

def price(name='',cost=998):
	print('商品名称:%s,价格:%d'%(name,cost))

这里就是默认给name参数’ ’ ,默认给cost参数998

>>> price('ABC')
商品名称:ABC,价格:998

但是,默认值的使用也有局限性,在这个函数里,默认情况是输入一个值,当我们输入price(6666)时,输出则会是

>>> price(6666)
商品名称:6666,价格:998

而且和关键字参数一样,默认值定义函数的时候,也只能以“左边不指定,右边指定”的 方式,反过来则会报错

>>> def price(name='ABC',cost):
	print('商品名称:%s,价格:%d'%(name,cost))
SyntaxError: non-default argument follows default argument

不定长参数: * 和 **

为了使用方便,我们在定义函数的时候是可以设置成不定长参数的

传递任意数量的参数值

格式:

函数名([参数1,参数2,.....参数n,]*不定长参数)

有一点要注意的是,带 * 的参数虽可以接受任意数量的值,但是一个自定义函数里只能有一个带 * 的参数,而且只能放在最右边。

例子如下:
这是一个记录了一天都完成什么任务的函数,完成的任务数量是不定的,所以要在result前面加一个*,这样result就是一个不定长参数

>>> def record(date,*result):
	print(date)
	temp = ''
	for i in result:
		temp += ' ' + i
	print(temp)

输入当日完成任务:

>>> record('4月27日','CSDNDay11','高数Day11','英语Day11')
427日
 CSDNDay11 高数Day11 英语Day11

而这个不定长参数是以什么形式保存的呢?type一下便知

...
print(type(result))
...
427<class 'tuple'>
 CSDNDay11 高数Day11 英语Day11

传递任意数量的键值对

格式:

函数名([参数1,参数2,.....参数n,]**不定长参数)

同样,一个自定义函数只能有一个带 ** 的不定长参数,而且只能放在最右边。唯一不同的就是,现在传递的是键值对。

依然以记录任务为例,但这次要改成键值对的样子:

def record(date,**result):
	print(date)
	print(result)

输入完成的任务(注意这里输入键和值的写法)

>>> record('4月27日',CSDN='Day11',高数='Day11',英语='Day11')
427{'CSDN': 'Day11', '高数': 'Day11', '英语': 'Day11'}

type一下就知道这次传递回来的是什么类型的数据了

<class 'dict'>

传递元组、列表、字典

传递元组

>>> def record(date,result):
	print(date)
	print(type(result))
	print(result)
	
>>> record('4月27日',('CSDNDay11','高数Day11','英语Day11'))
427<class 'tuple'>
('CSDNDay11', '高数Day11', '英语Day11')

传递列表

函数同上,只不过在输入的时候换成列表了

>>> record('4月27日',['CSDNDay11','高数Day11','英语Day11'])
427<class 'list'>
['CSDNDay11', '高数Day11', '英语Day11']

传递字典

函数依旧不变,输入再改成字典

>>> D = {'CSDN': 'Day11', '高数': 'Day11', '英语': 'Day11'}
>>> record('4月27日',D)
427<class 'dict'>
{'CSDN': 'Day11', '高数': 'Day11', '英语': 'Day11'}

传递可能产生的问题

以列表为例,自定义一个单价打折函数:

>>> def discount(Mobile,price):
	print(Mobile)
	price[1] *= 0.9
	print(price)

输入

>>> L = ['Mate30',4999]
>>> discount('HUAWEI',L)
HUAWEI
['Mate30', 4499.1]

但是当我们再查看列表L的时候

>>> L
['Mate30', 4499.1]

我们发现,L也被改变了,这是因为无论传递前还是传递后的对象(列表、元组、字典)都是指向同一个地址的,一旦我们在自定义函数内部让对象发生改变,这个改变会导致输入的对象也发生改变,而这往往是我们不希望发生的,所以为了避免这个现象发生,我们可以复制该对象。
函数应改为:

>>> def discount(Mobile,price):
	print(Mobile)
	L1 = price.copy()
	L1[1] *= 0.9
	print(L1)

再重新输入

>>> discount('HUAWEI',L)
HUAWEI
['Mate30', 4499.1]
>>> L
['Mate30', 4999]

如此就会避免这个问题


今天就说这些了,本想着把匿名和递归函数一并说了,没想到已经写了这么多了,那这两位就放到明天好了。我是康.尚在学习中的普通学生,欢迎各位与我一起学习,共同进步!
在这里插入图片描述

原创文章 23 获赞 103 访问量 2690

猜你喜欢

转载自blog.csdn.net/k_ksy/article/details/105782098