强基初中数学&学Python——第二十课 Python函数的各种参数形式

    我们已经学过Python函数的无参数形式和按位传值参数形式,这一课里全面说明Python函数的参数形式。

一、带默认值的参数

    分数由分子和分母构成,但为什么不输入参数和只输入分子

>>>from fractions import Fraction
>>>Fraction(123)

Fraction(123, 1)

>>>Fraction()

Fraction(0, 1)

也能构造成分数呢?原来输入的参数有默认值

class fractions.Fraction(numerator=0denominator=1)。

分子(numerator)的默认是0,分母(denominator)的默认值是1,当只输入分子123时,分母采用默认值1,所以构成的分数是Fraction(123, 1);都不输入时,分子默认0,分母默认1,所以构成的分数是Fraction(0, 1)。

    默认值是在函数定义处被计算的,并且只会执行一次,所以

i = 5        #i被赋值5

def f(arg=i):   #arg的默认值被赋值i,因为这时i=5,所以arg的默认值是5

    print(arg)

 

i = 6           #i被赋值6,但arg的默认值不会被重新计算。
f()

会打印 5;

def f(a, L=[]):      #L的默认值是一个列表(已固定,可编辑元素)
    L.append(a)      #往列表中添加元素
    return L        #返回列表

print(f(1))          #采用默认值调用函数
print(f(2))

print(f(3))

print(f(4, []))     #不采用默认值调用函数

这将打印出

[1]
[1, 2]

[1, 2, 3]

[4]

。如果你不想要在后续调用之间共享默认值,采用None默认值,并且在函数体内对输入对象初始化,你可以这样写这个函数:

def f(a, L=None):

    if L is None:

L = []
    L.append(a)

   return L

 

print(f(1))          #采用默认值调用函数

print(f(2)) 

print(f(3))   

print(f(4, []))     #不采用默认值调用函数

将打印出

[1]
[2]

[3]

[4]

    有默认值的参数务必要在无默认值的参数后:

二、关键字调用函数

    下面是输入初一(7)班学生的姓名,性别和年龄的程序

因为黄小丽的年龄是默认值12岁,就不输入年龄,但结果打印出

。为什么电脑不按你的意思工作呢?因为你采用的是按位调用函数,“黄小丽”赋值给name,“女”赋值给age,sex不输入就采用默认值“男”。如果使用按位调用,只能这样调用

age的默认值没用上。
    有没有方法不用输入age,也不会出错的呢?

    有!就是关键字调用函数。原来函数的参数名称,对于函数体内是形式参数名称,对于调用者不但是入口参数名称,也是入口参数的“关键字”。只要使用

关键字=值

的形式调用函数,就可以精准赋值。修改后的程序和结果如下:

。从上图中可以看到,按位传值和关键字传值可以同时使用,这样就要注意不能重复传值

三、任意的参数列表

    如果还要输入学生的家长(可以多个,数量不定),就要加入一个任意的参数列表(在标识符前加一个*),修改程序

打出的结果

,显然,结果是错的!原来任意的参数列表(*pOrg)之前不可以有有默认值的参数(在Python中认为有默认值的参数是键值参数),进一步修改程序

打出的结果

OK了!也注意到,任意的参数列表是一个元组。

四、任意的参数字典

    比如还要输入爱好、最喜欢的食物、专长、最喜欢的歌等等一些项目,就要采用"任意的参数字典",在参数之前加**。再修改程序

,语法错误!原来任意的参数字典只能放在参数最后。再修改程序

打出的结果

OK了。也注意到任意的参数字典是一个字典数据类型。

五、特殊参数

     如果学生的名字总是第一个参数,希望仅按位传值;性别和年龄两个参数如果按位传值容易搞错,规定仅按关键字传值;把家长这个任意的参数列表变更为父亲、母亲、其他亲属(任意的参数列表)0到多个家长,可以按位也可以按关键字传值,应该怎样做呢?

    限位置传值的参数一定要放在前面,在这些参数之后放一个特殊参数"/"(正斜杠);限关键字传值的参数一定要放后面,在这些参数之前放一个特殊参数"*"(星号);在"/"和"*"之间的参数可以按位也可以按关键字传值。程序修改如下

,有语法错误!原来在参数“*other_rels”之后的参数“*”是多余的了,因为参数“*other_rels”之后的参数一定要通过键值才能输入,把程序修改为

后,打印出的结果

OK了。

六、解包参数列表

    与参数的打包(任意的参数列表和任意的参数字典)相对,要把列表、元组或字典解包成单独的参数,就是解包参数。举例说明:

解包列表或元组,在调用函数时,在列表或元组之前加“*”号,打出的结果

显然,数据解包后正确传给了相应的参数;

解包字典,在调用函数时,在字典之前加“**”号,打出的结果

显然,数据解包后正确传给了相应的参数

练习题:按本课的测试,输入代码自行测试一次。