美文网首页
python 基础知识第10讲:函数的初识、参数、解包

python 基础知识第10讲:函数的初识、参数、解包

作者: 小海怪的互联网 | 来源:发表于2019-07-13 12:05 被阅读0次

    1.函数

    函数也是一个对象,就是我们在内存当中所开辟的一块区域,通过一些代码块实现特定的功能 。
    可以用来保存一些可执行的代码,并且可以在需要的时候,对这些代码(语句)进行多次调用。

    • 内置函数
    • 自定义函数

    1.1函数的定义

    函数名必须按照标识符的命名规范
    (可以包含字母 数字 下划线 但是不能以数字开头)

    语法:
    def 函数名([形参1,形参2...]):
    代码块

    注:函数中保存的代码块不会立即执行,需要调用函数代码才会执行
     def fn():
         print('这个是我第一个函数')
         print('哈哈哈')
         print('同学们好')
         print('又到了周末')
    

    print(fn)
    <function fn at 0x00000000003D1E18>
    此时打印出来的是一个函数所在的内存地址
    fn是函数对象 fn() 调用函数

    1.2函数的调用

    函数对象()

    2函数的参数

    先看一个例子

     def fn2(a,b):
    
         print('a =',a)
          print('b =', b)
         print(a,'+',b,'=',a+b)
     fn2(2,3)
     fn2(222,666)
    
    • 1在定义函数的时候,可以在函数后面的括号定义不等的形参
    • 多个形参我们用 , 隔开
    • 形参(形式参数) 定义形参就相当于在函数内部声明了变量,但是不是赋值
    • 2 实参(实际参数) 指定了形参,那么你在调用函数的时候必须传递实际参数
    • 实际参数将会赋值给对应的形参,就是你有几个形参就需要传递几个实参

    2.1函数的参数传递方式

    默认值

    定义形参的时候,可以给形参指定默认值,指定了默认值之后,
    如果用户传递了实参默认值不会发挥任何作用,如果用户没有传递,则默认值会发挥作用

    观看以下例子

    def fn(a,b,c=20):
        print('a = ',a)
        print('b = ',b)
        print('c = ',c)
    fn(1,2,3)
    

    输出结果为:
    a = 1
    b = 2
    c = 3
    此结果符合:如果用户传递了实参默认值不会发挥任何作用 此结论

    def fn(a,b,c=20):
        print('a = ',a)
        print('b = ',b)
        print('c = ',c)
    fn(1,2)
    

    输出结果为:
    a = 1
    b = 2
    c = 20
    此结果符合:如果用户没有传递,则默认值会发挥作用

    2.1.1函数实参的传递方式

    • 位置传递

    位置参数就是将对应位置的实参赋值给对应位置的形参.
    第一个实参赋值给第一个形参,第二个实参赋值给第二个形参...

    • 关键字参数

    关键字参数,可以不按照形参定义的顺序去传递,而根据参数名去传递
    如系统内置的一些,print('111',end='')

    def fn(a = 5,b = 10,c = 20):
         print('a =',a)
         print('b =',b)
         print('c =',c)
    fn(b=1,c=2,a=5)
    
    • 位置参数和关键字参数可以混合使用

    混合使用的时候关键字和位置参数时,必须将位置参数写到关键字参数前面

    def fn(a = 5,b = 10,c = 20):
         print('a =',a)
         print('b =',b)
         print('c =',c)
    fn(1,c=8)
    

    2.1.2函数实参的类型

    实参可以传递任意类型的对象
    但是如果当一个函数中当出现数据相加,但是传递的参数当中有字符串时,虽然ide不会报错,但是实际函数执行的时候会报错,我们可以通过异常处理机制进行处理

     def fn2(a):
       print('a =', a)
    # b = 123
    # b = 'python'
    # b = None
    # b = False
    # fn2(b)
    # fn2(fn)  传递一个函数,指向的是这个函数的内存地址 
    
    • 我们看下面一个例子
    def fn4(a):
        a = 20
        a[0] = 50
        print('a =',a,id(a))
    
    c = 10
    fn4(c)
    

    执行结果如下:
    a = 20 1548185664

    c= 10
    通过上面的结果们可以看出:
    在函数中对形参进行重新赋值,不会影响其他的变量

    • 再看一个例子
    def fn4(a):
        a[0] = 50
        print('a= ',a,id(a))
    
    c = [1,2,3]
    fn4(c)
    print('c= ',c,id(c))
    

    执行结果为:
    a= [50, 2, 3] 2591199028936
    c= [50, 2, 3] 2591199028936
    通过结果我看可以看出此参数c传递后,形参a和c指向的是同一个对象,所以在内部修改相应的元素,c也会变

    • 再看下面的例子
    def fn4(a):
        a[0] = 50
        print('a= ',a,id(a))
    
    c = [1,2,3]
    fn4(c.copy())
    print('c= ',c,id(c))
    

    执行结果为:
    a= [50, 2, 3] 2757291878344
    c= [1, 2, 3] 2757289404104
    由上面的结果我们可以得出:
    如果你在传递的是一个可变对象的时候,而你又不希望我在函数内部的操作影响到函数外部的时候。那么你就可以考虑传递一个对象的副本,通过对象.copy()的方式将其复制一份

    2.2函数的不定长参数

    其实就是将多余的参数放进一个包里

    (*a处理位置参数 **a处理的是关键字参数)

    在定义函数时,可以在形参前边加上一个*,这样做的好处是这个形参可以获取到所有的实参.
    它将会把所有的实参保存到一个元组当中

    先看一段代码:

    #定义一个函数,求任意个数的和
    def sum(a,b,c):
        print(a,b,c)
    
    sum(1,2,3)
    

    此时当我们想传起过3个数的时候,程序会报错,这个时候我们可以使用不定长参数来解决
    我们可以将上面的代码改写成下面这样:

    def sum(*a):
        # 定义一个变量 用来保存的结果
        result = 0
        # 遍历元祖,并将元祖中的数进行计算
        for n in a:
            result = result + n
        print(result)
    sum(12,45,46,55,20)
    

    执行结果为:178

    ===================================================================

    不定长参数也可以和其他参数配合使用
    不定长参数不是必须写在最后,但是要注意,带*的参数后面的所有参数,必须以关键字的参数形式传递

    def fn2(*a,b,c):
        print('a =',a)
        print('b =',b)
        print('c =',c)
    
    fn2(1,2,3,b=4,c=5)
    

    结果为:
    a = (1, 2, 3)
    b = 4
    c = 5

    ===================================================================

    ** 形参可以接受其他的关键字参数,它会将这些参数统一保存到一个字典当中
    自定的key就是关键字的名字,字典的value就是参数的值
    **形参只能有一个 并且必须写在所有参数后面

     def fn3(b,c,**a):
         print('a =', a)
         print('b =', b)
         print('c =', c)
     fn3(b=1,d=2,c=3,e=5,f=20)
    

    执行结果为:
    a = {'d': 2, 'e': 5, 'f': 20}
    b = 1
    c = 3

    2.3函数参数的解包

    *param 解包

    我们先看一下下面的代码:

    def fn4(a,b,c):
        print('a =', a)
        print('b =', b)
        print('c =', c)
    t=(1,2,3)
    fn4(t)
    

    此时执行程序会直接报错

    我们把程序稍做调整:

    def fn4(a,b,c):
        print('a =', a)
        print('b =', b)
        print('c =', c)
    t=(1,2,3)
    fn4(t[0],t[1],t[2])
    

    上面的方法虽然能解决,但是这只是参数少的情况下,如果我有100个,1000个的时候会写死人的,所以上面的方法并不合适,我们需要把元组赋值给形参

    我们根据之前学的方法,可以在序列类型的参数前添加*,这样它会自动将序列当中的元素依次作为参数传递,这里要求序列当中的元素的个数必须和形参的个数保持一致
    代码如下:

    def fn4(a,b,c):
        print('a =', a)
        print('b =', b)
        print('c =', c)
    t=(1,2,3)
    fn4(*t)
    

    执行结果:
    a = 1
    b = 2
    c = 3
    上面的这种将序列参数拆开进行传递方式就被称之解包

    **param 解包

    这种方式用于将字典类型的参数进行解包,因为之前我们在封包的时候通过 param,可以将多余的参数解析为一个字典,但是要注意把字典当参数进行解包时,字典当中的key必须是以关键字的参数传递方式才行

    def fn4(a,b,c):
        print('a =', a)
        print('b =', b)
        print('c =', c)
    t={'a':1,'b':2,'c':3}
    fn4(**t)
    

    执行结果:
    a = 1
    b = 2
    c = 3

    相关文章

      网友评论

          本文标题:python 基础知识第10讲:函数的初识、参数、解包

          本文链接:https://www.haomeiwen.com/subject/qlkpkctx.html