1.形参和实参

函数从调用的角度来说,分为形式参数和实际 参数。形参是指函数创建和定义过程中小括号里的参数;而实参指得是函数在被调用过程中传递进来的参数。如下所示

>>> def MyFirstFunction(name):
    '函数定义过程中的name是叫形参'
    #因为Ta只是一个形式,表示占据一个参数位置
    print('传递进来的' + name + '叫做实参,因为Ta是具体的参数值!')

>>> MyFirstFunction('小甲鱼')
传递进来的小甲鱼叫做实参,因为Ta是具体的参数值!


2.函数文档(.__doc__)
给函数写文档是为了让别人可以更好的理解你的函数,所以这是一个好习惯。函数文档的作用是描述该函数的功能。

>>> def MyFirstFunction(name):
'函数定义过程中的name是叫形参'
#因为Ta只是一个形式,表示占据一个参数位置
print('传递进来的' + name + '叫做实参,因为Ta是具体的参数值!')


>>> MyFirstFunction.__doc__  #MyFirstFunction没有()
'函数定义过程中的name是叫形参'
>>>

我们发现,在函数开头写下的字符串是不会打印出来的,但它作为函数的一部分存储起来。这个称为函数文档字符串,它的功能跟注释一样。

与注释不同的是,函数文档字符串可以通过特殊属性 ._ _doc_ _(注:._ _doc_ _两边分别是两条下划线):

也可以使用help()函数查看函数的文档

函数文档写在一个字符串里面,写2个,只会打印出第一个,第二个不会打印打出,例如:

>>> def MyFirstFunction(name,age):
    '这是一个函数文档'
    '用来记录函数的使用记录'
    print('班长:'+ name +',年龄:' + age)

    
>>> MyFirstFunction.__doc__
'这是一个函数文档'
>>> 

 

3.关键字参数

普通的参数叫做位置参数,使用位置参数可以解决程序员在调用一个函数时候,搞乱位置参数的顺序,以至于函数无法按照预期实现的潜在问题。

>>> def saySome(name,words):
    print(name + "—>" +words)

    
>>> saySomething("小甲鱼","让编程改变世界!")
小甲鱼—>让编程改变世界!
>>> saySome("让编程改变世界!","小甲鱼")
让编程改变世界!—>小甲鱼
'为了不让调用的参数位置弄混,加上关键字参数,就不会出错了'
>>> saySome(words="让编程改变世界!",name="小甲鱼") 小甲鱼—>让编程改变世界!

关键字参数其实就是在传入实参时指定形参的变量名,在调用函数的时候使用的

4.默认参数
默认参数就是在函数定义的时候,给形参赋予了默认值的参数:
>>> def saySome(name="小甲鱼",words="让编程改变世界!"):
    print(name + '—>' +words)

    
>>> saySome()  #调用函数时没有参数,就会去找默认参数
小甲鱼—>让编程改变世界!
>>> saySome("小鱿鱼","也可以改变世界") #重新赋予实参,会调用函数时会调用实参,不会调用默认的参数
小鱿鱼—>也可以改变世界

 

>>> def test1(name = '甲鱼',age = '20'):
    print('语文老师的名字是:'+ name +',年龄:' + age)
    
>>> test1()
语文老师的名字是:甲鱼,年龄:20
>>> test1('youyu')
语文老师的名字是:youyu,年龄:20
>>> test1(name = 'lucu')
语文老师的名字是:lucu,年龄:20
>>> 

 

使用默认参数的话,就可以不带参数去调用函数。所以,它们之间的区别是:关键字参数是在函数调用的时候,通过参数名指定要赋值的参数,这样做就不怕因为搞不清参数的顺序而导致函数的调用出错;而默认参数是在参数定义过程中,为形参赋初值,当函数调用的时候,不传递参数,则默认使用形参的初始值代替。

5.收集参数(可变参数)
表示Function(*param)
收集参数在大多数的时候被称作可变参数,仅需要在参数前面加上星号(*)即可:
>>> def TestFun(*param):
    print('函数的长度是:',len(param))
    print('第二个参数是:',param[1])

    
>>> TestFun(1,'hello',3.14)
函数的长度是: 3
第二个参数是: hello
>>> 

Python就是把标志为收集参数的参数们打包成一个元组。

注意:如果在收集参数的后面还需要指定其它参数,在调用函数的时候就应该使用关键字参数来指定,否则Python就都会把你的实参都列入收集参数的范畴。

>>> def TestFun(*param,dec):
    print('函数的长度是%d' % len(param))
    print('最后一个参数是:',param[-1])

    
>>> TestFun(2,4,6,'world',7,8)
Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    TestFun(2,4,6,'world',7,8)
TypeError: TestFun() missing 1 required keyword-only argument: 'dec'
>>> TestFun(2,4,6,'world',7,dec=8)
函数的长度是5
最后一个参数是: 7
>>> 

建议:

在参数中带有收集参数是,可以将其它参数设置为默认参数,这样不容易出错

>>> def TestFun(*param,dec=9):
    print('函数的长度是%d' % len(param))
    print('最后一个参数是:',param[-1])

    
>>> TestFun(2,4,6,'world',7,5)
函数的长度是6
最后一个参数是: 5
>>> 
>>> def test(*param,keyname=8):
    print('收集参数是:',param)
    print('关键字参数是:',keyname)

>>> test(1,2,3,4,9)
收集参数是: (1, 2, 3, 4, 9)
关键字参数是: 8
>>> 

课后习题及答案

0.请问一下哪个是形参哪个是实参?

>>> def MyFun(x):
    return(x**3)
    y = 3
    print(MyFun(y))
    
>>> MyFun(3)
27

  x是形参,y是实参


1.函数文档和直接用#为函数写注释有什么不同
  函数文档可以用属性.__doc__调用,即Function.__doc__,

   #注释


2.使用关键字参数,可以避免什么问题的出现
   可以避免调用函数是参数传递错误的问题


3.使用help(print)查看print()这个BIF有哪些默认参数?分别起到什么作用?
   
4.默认参数和关键字参数表面最大的区别是什么?
   默认参数在函数定义时就赋值,关键字参数是在函数调用时赋值

动动手:
0.编一个符合以下要求的函数:
    a)计算打印所有参数的和乘以基数(base=3)的结果
    b)如果参数中最后一个参数为(base=5),则设定基数为5,基数不参与求和计算。

>>> def Sum_X_base(*param,base = 3):
    result = 0
    for each in param:
        result += each
    if param[-1] == 5:
        base = 5
    Sum = result *base
    return Sum

>>> Sum_X_base(1,2,3)
18
>>> Sum_X_base(1,2,5)
40
>>> 

 

1.寻找水仙花数
    如果一个3位数等于其各位数字的立方和,则称这个数为水仙花数,例如153=1^3+5^3+3^3,因此153是一个水仙花数,编写一个程序,找出所有的水仙花数。

Narcissus [nɑːˈsɪsəs]:水仙

>>> def FoundNarcissus():
    for each in range(100,1000):
        temp = each
        sum = 0
        while temp:
            sum += (temp % 10)**3
            temp = temp // 10
        if (sum == each):
            return each

>>> FoundNarcissus()
153
>>> 

 正确的代码如下:

>>> def Narcissus():
    for each in range(100,1000):
        temp = each
        result = 0
        while temp:
            result += (temp %10)**3
            temp = temp // 10
        if (result == each):
            print(each)

>>> Narcissus()
153
370
371
407
>>> 

 

2.编写一个函数findstr(),该函数统计一个长度为2的子字符串在另一个字符串中出现的次数,例如:假如输入的字符串为:You cannot improve your past,but you can improve your future.Once time is wasted,life is wasted.子字符串为im,该函数执行后打印“子字符串在目标字符串中共常出现3次”。

def findStr(desStr, subStr):
    count = 0
    length = len(desStr)
    if subStr not in desStr:
        print('在目标字符串中未找到子字符串!')
    else:
        for each1 in range(length-1):      
            if desStr[each1] == subStr[0]:
                if desStr[each1+1] == subStr[1]:
                    count += 1             
    print('子字符串在目标字符串中共出现次',count)

    
desStr = input('请输入目标字符串:')
subStr = input('请输入子字符串(两个字符):')
print(findStr(desStr, subStr))