变化的参数
多个参数输入
位置参数
关键字参数
默认值
不定长参数: * 和 **
传递任意数量的参数值
传递任意数量的键值对
传递元组、列表、字典
传递元组
传递列表
传递字典
传递可能产生的问题
多个参数输入
昨天程序里大多是只有一个参数的函数,不需要考虑其它问题。当我们需要多参数时,有以下几种传递办法可选
位置参数
位置参数,就是在传递参数值的时候,必须和函数定义的参数一一对应,否则传递会发生误传甚至报错。
例如下面这个有两个参数的函数:
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日’,’Day11′,’高数Day11′,’英语Day11′)
4月27日
Day11 高数Day11 英语Day11
而这个不定长参数是以什么形式保存的呢?type一下便知
…
print(type(result))
…
4月27日
Day11 高数Day11 英语Day11
传递任意数量的键值对
格式:
函数名([参数1,参数2,…..参数n,]**不定长参数)
同样,一个自定义函数只能有一个带 ** 的不定长参数,而且只能放在最右边。唯一不同的就是,现在传递的是键值对。
依然以记录任务为例,但这次要改成键值对的样子:
def record(date,**result):
print(date)
print(result)
输入完成的任务(注意这里输入键和值的写法)
>>> record(‘4月27日’,=’Day11′,高数=’Day11′,英语=’Day11′)
4月27日
{”: ‘Day11’, ‘高数’: ‘Day11’, ‘英语’: ‘Day11’}
type一下就知道这次传递回来的是什么类型的数据了
传递元组、列表、字典
传递元组
>>> def record(date,result):
print(date)
print(type(result))
print(result)
>>> record(‘4月27日’,(‘Day11′,’高数Day11′,’英语Day11’))
4月27日沈阳妇科医院 http://yyk.39.net/hospital/fc843_doctors.html
(‘Day11’, ‘高数Day11’, ‘英语Day11’)
传递列表
函数同上,只不过在输入的时候换成列表了
>>> record(‘4月27日’,[Day11′,’高数Day11′,’英语Day11′])
4月27日
[‘Day11’, ‘高数Day11’, ‘英语Day11’]
传递字典
函数依旧不变,输入再改成字典
>>> D = {”: ‘Day11’, ‘高数’: ‘Day11’, ‘英语’: ‘Day11’}
>>> record(‘4月27日’,D)
4月27日
{‘: ‘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]
如此就会避免这个问题
…
…