zoukankan      html  css  js  c++  java
  • 第七章 函数基础

    # 第七章 函数基础
    ## 一、函数定义
    ### 1、为什么python需要使用函数?
      - 如果你不使用函数,将会出现:代码冗余,复杂度增大,组织结构不够清晰,可读性差,可扩展性差等等,这些缺点却是函数的优点之处。
      - 函数是带名字的代码块,用于完成具体的任务,要执行函数定义的特定任务,可调用该函数。在程序中多次执行同一项任务时,你无需反复编写该任务的代码,而而只需调用该任务的函数,让Python运行其中的代码。
      - 通过使用函数,程序的编写、阅读、测试和修复都将会更容易。
    ### 2、定义函数
    函数定义格式如下:
    ```python
    def 函数名(参数):
      pass
      return 表达式
    ```
    函数名命名规则:字母、数字和下划线组成,和变量命名规则一致。
     
    pass在这里表示什么都没有,不执行任何操作。
     
    return后面可以返回任何表达式,但不能是赋值语句;return后面没有返回值的话,默认None。
     
    下面是一个打印问候语的简单函数,名为greet():
    greet.py
    ```python
    def greet():    #数代码块以 def 关键词开头,后接函数标识符名称和圆括号()
      print('Hello!')    #打印简单的问候语Hello
      
      
    greet()    #调用函数,表示去执行该函数
    ```
      这个实例演示了最简单的函数结构。①处的代码行使用关键字def来告诉python你要定义一个函数,函数名为greet(),括号内可指定函数为完成任务需要带的参数信息,在这里,这个函数不需要任何信息就能完成其工作,因此括号是空的(括号是必不可少)。最后,定义以冒号结束。
      
      紧跟在def greet():后面的所有缩进构成了函数体。②处是函数体内唯一一行代码,greet()函数只做一项工作,打印Hello!。
      
      
      要使用这个函数,可调用它。如④处所示,由于这个函数不需要任何信息,以此调用它只需要输入greet()即可。运行以上代码便可得到结果:
      
    ---
      Hello!
      
    ---
      
    ## 二、函数参数
    ### 1、什么是函数参数
      函数能把具有独立功能的代码块组织成为一个小模块,在需要的时候调用,而函数的参数能增加函数的通用性,针对相同的数据处理逻辑,能够适应更多的数据。
      
      在使用的过程中,参数有两种形式:形式参数和实际参数,可简单概括:
      - 形参是定义函数的参数
      - 实参是调用函数的参数
      
      根据实际参数类型不同,将实际参数传递给形参的方式有两种:值传递和引用传递,在下一小节--形参和实参详细讲解。
    ### 2、形参和实参
      形参:函数完成其工作所需的一项信息。即形式参数当作变量使用,进行需要的数据处理。可传多个形参,函数声明时的形参数量和调用函数时传入的实参数量要一致,声明的形参顺序和传入的实参顺序也要一致。
      
      实参:调用函数时传递给函数的信息,即按照函数定义的参数顺序,把希望在函数内部处理的数据,通过参数传递。
      
      将函数名为greet()的函数修改为,可以让函数不仅仅向用户显示Hello!,还可以灵活加入想加的username参数,要求这个函数被调用它时给username指定一个值。调用greet()时,可将名字传递给它,如下所示:
    ```python
    def greet(username):
      print("Hello,"+username+"!")
      
    greet('jim')
    ```
    执行该代码,结果为:
     
    ---
      Hello,jim!
      
    ---
      这个实例展示函数里实参和形参的含义。在greet('jim')中,将实参‘jim’传递给函数greet(),这个值被存储在形参username中。
      
      值传递:实参为不可变对象,传递给形参后,形参的值改变,实参值不变。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
     
      引用传递:实参为可变对象,传递给形参后,形参的值改变,实参值改变。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响。
      
    ---
    注意:在第二、三章介绍的python的数据类型,字符串(strings), 元组(tuples), 和数列(numbers)是不可更改的对象,而列表(list),字典(dict)等则是可以修改的对象。
     
    ---
    ```python
    def demo(st):
      print(st)
      st+=st
      print(st)
     
    end1='123'    
    demo(end1)    #实参为字符串,是不可变对象,形参的值改变,实参值不变
    print("函数调用后的end1:"+end1)
     
    end2=[1,2,3]
    demo(end2)    #实参为列表,是可变对象,形参的值改变,实参值改变
    print("函数调用后的end2:"+str(end2))
    ```
    执行该代码,结果为:
     
    ---
    123          
     
    123123
     
    函数调用后的end1:123
     
    [1, 2, 3]
     
    [1, 2, 3, 1, 2, 3]
     
    函数调用后的end2:[1, 2, 3, 1, 2, 3]
     
    ---
     
    ### 3、传递实参
      函数的传递实参方式很多,可划分为:必备参数、关键字参数、默认参数、可变参数(不定长参数)、组合参数,总共5种。
    #### 1)必备参数(位置参数)
      调用函数时,Python必须将函数调用中的每个实参都关联到函数定义中的每个形参。所以,最简单的关联方式基于实参的顺序,这种关联方式被称为位置参数。位置参数要求实参的顺序和形参的顺序相同。
    ```python
    def test(name,age):
      print("My name is " +name+","+" I'm "+age+" years old today.")
     
    test('Tom','18')
    test('Jerry','16')
    ```
    执行该代码,结果为:
     
    ---
    My name is Tom, I'm 18 years old today.
     
    My name is Jerry, I'm 16 years old today.
     
    ---
      这个函数的定义表明,形参参数为:name和age,那么,在调用函数时,需要传递两个实参,而且是与形参顺序对应的实参,如果在这个函数调用时,实参是先指定age('18'),再指定name('Tom'),那么结果就会打印成:My name is 18, I'm Tom years old today.。这结果就不是正确的表达意义了。
     
      调用函数多次是一种效率极高的工作方式。只需再调用函数,写入新的实参,就可以描述新的表意。
    #### 2)、关键字参数
      关键字参数要求每一个实参都由变量名和值组成,即直接在实参中将名称和值关联起来了,因此向函数传递实参时不会混淆。关键字实参让你无需考虑函数调用时的实参顺序,还清晰指出了函数调用中各个值的用途。
    ```python
    def test(name,age):
      print("My name is " +name+","+" I'm "+age+" years old today.")
     
    test(name='Tom',age='18')
    test(age='16',name='Jerry')  
    ```
      执行该代码,结果和位置参数的输出结果一样。那么,总结出关键字实参的顺序无关紧要,因为可以准确地指定函数定义的形参名。
    #### 3)默认参数
      函数定义时,可为参数设置一个默认值,在调用函数中形参提供了实参时,Python将使用指定的实参值;否则使用形参的默认值。所以,在形参给定默认值后,可在函数调用中省略相应的实参。使用默认参数可简化函数调用。
    ```python
    #如果介绍的都是18岁的同学,就可将形参参数age默认值设置为'18'。
    def test(name,age='18'):
      print("My name is " +name+","+" I'm "+age+" years old today.")
     
    test(name='Tom')
    test(name='Jerry')
    ```
    执行该代码,结果和以上两种传递参数的输出结果一样。
     
    ---
    注意:使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的形参,这让Python依然能够正确解读位置实参。
     
    ---  
    #### 4)可变参数(不定长参数)
      有时候,你预先不知道函数需要接受多少个实参,那么,可以传入一个可变参数,即不定长参数,这样,不管调用函数时给了多少个实参,都能够将他们统统收入囊中。
      
      可变参数有两种形式:一种是*args,另一种是**kwargs。
     
      *args:这种形式表示接受任意多个实际参数将其放到一个元组中。
     
      **kwargs:这种形式表示接受任意多个实际参数将其放到一个字典中,类似关键字参数。
    ```python
    #*args形式
     
    def demo(*args):
      print('我喜欢的城市:')
      for i in args:
        print(i)
     
    demo('深圳','杭州','上海')    #调用形式:可直接传一个tuple
    city=['北京','广州','哈尔滨']     #也可以通过list或者tuple的变量传
    demo(*city)
     
    #**kwargs形式
    def fun(name,age,**kwargs):
        print("name:",name,"age:",age,"other:",kwargs)
     
    fun('Tom',16,sex='male',job='teacher')    #结合位置参数和不定长参数传递实参
     
    def fun1(**kwargs):
        print("name:age")
        for i,j in kwargs.items():
            print(i,':',j)
     
    di={'Tom':23,'jin':12}    #也可以通过字典变量传
    fun1(**di)
    ```
    执行该代码,结果为:
     
    ---
    name: Tom age: 16 other: {'sex': 'male', 'job': 'teacher'}
     
    name:age
     
    Tom : 23
     
    jin : 12
     
    ---
    #### 5)组合参数  
      在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数组合使用。但是注意,参数定义的顺序必须是:必备参数、默认参数、可变参数、关键字参数。
      比如定义一个函数,包含上述若干种参数:
    ```python  
    def f1(a, b, c=0, *args, **kw):
        print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
     
    def f2(a, b, c=0, *,d, **kw):
        print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
     
    f1(1, 2)    #结果为:a = 1 b = 2 c = 0 args = () kw = {}
     
    f1(1, 2, c=3)    #结果为:a = 1 b = 2 c = 3 args = () kw = {}
     
    f1(1, 2, 3, 'a', 'b')    #结果为:a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
     
    f1(1, 2, 3, 'a', 'b', x=99)    #结果为:a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
     
    f2(1, 2, d=99, ext=None)    #结果为:a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}
     
    args = (1, 2, 3, 4)    
    kw = {'d': 99, 'x': '#'}
    f1(*args, **kw)    #结果为:a = 1 b = 2 c = 3 args = (4,) kw = {'d': 99, 'x': '#'}
     
    args = (1, 2, 3)
    kw = {'d': 88, 'x': '#'}
    f2(*args, **kw)    #结果为:a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'}
    ```
    ## 三、课堂练习
    ### 1、编写一个名为hobby()的函数,它创建一个描述人物的爱好的字典。这个函数应接受任务的名字,年龄和性别,并返回名字和爱好的字典。通过使用组合参数的形式展示这一章所学的传递参数的知识。
    ## 四、上一节课堂练习答案
    ### 1、打印9*9乘法口诀表
      九九乘法表的阵型图片如下:
     

     

    - 乘法表几行几列?
     
    9*9
     
    - 怎么打印横排和竖排?
     
    横排: print('',end=' ')
     
    竖排: print('')
     
    - 那么如何同时打印横竖排?
     
    观察第一张乘法表,第一行乘数都是1,被乘数就是1-9,可以理解为,当乘数都是1时,被乘数遍历1-9这九个数字。
    ```python
    for i in range(1,10):
      for j in range(1,10):
        print('%s*%s=%s'%(j,i,i * j),end=' ')
      print()
    ```
    执行该代码,就能够得到第一张九九乘法表,那么,如何改为第二章典型的九九乘法表呢?观察,可看出,需要删除右上角那一半,都是乘数比被乘数大,可以根据这个条件进行判断。
    ```python
    for i in range(1,10):
         for j in  range(1,10):
            if j > i:
              break
            print("%s*%s=%s"%(j,i,j * i),end=' ')
         print()
    #条件判断还可以写成更简练的代码,可以私下查资料,还有很多大同小异的代码块也能实现九九乘法表。
    for i in range(1,10):
         for j in  range(1,i+1):
            print("%d*%d=%d"%(j ,i , j * i),end=' ' if j<i else ' ')
    ```
    ### 2、打印range(31)除带7或是7的倍数的数以外的所有数,并注明奇数还是偶数。
    - 7的倍数怎么确定:
     
    i%7==0
     
    - 带7的数怎么确定?
     
    i//10==7
     
    也可以将数值转换为字符串,通过判断'7'是否在这个字符串里面
    ```python
    for i in range(31):
      if i%10==7 or i%7==0:
        continue
      else:
        result = str(i)+'是偶数' if i % 2 == 0 else str(i)+'是奇数'
        print(result)
    ```
     
     
     
      
     
     
     
     
    如有问题请留言,谢谢!
  • 相关阅读:
    1027: C语言程序设计教程(第三版)课后习题7.5
    1026: C语言程序设计教程(第三版)课后习题7.4数组排序
    1025: C语言程序设计教程(第三版)课后习题7.3
    求n之内素数
    迭代
    Java入门:char与byte的区别
    使用MyEclipse 2014创建项目
    Java入门:MyEclipse安装与破解教程
    Java入门:JDK与Eclipse之类的集成开发工具的关系
    Java入门:Java环境变量PATH、CLASSPATH、JAVA_HOME
  • 原文地址:https://www.cnblogs.com/yunsi/p/13202055.html
Copyright © 2011-2022 走看看