• 第十一篇 Python函数之定义&形参&实参&位置参数&关键字参数&可变长参数&默认参数


    函数的定义:函数是为了完成某一特定功能的,函数是逻辑结构化和过程化的一种编程方法

    函数的定义格式,函数一般都是有返回值的

     #语法

      #函数名要能反映其意义
      def 函数名(参数1,参数2,参数3,...):
      '''注释'''
        函数体
        return 返回的值

    def test(x):
        '''
        函数功能:计算 2*x+1    正规军写函数前都会写注释,说明这个函数要实现的功能
        :param x:整形数字
        :return: 返回计算结果
        '''
        y=2*x+1
        return y
    
    #函数的调用,需要传入参数
    print(test(4))

    print(test) # 代表番函数的内存地址被打印出来 <function test at 0x00AFB618>
    #结果 9

    # 再定义一个test函数,那么本段程序有两个test函数,怎么执行?
    # Python 解释器是从上到下执行的,当执行到test()时,是不带参数的,所以该段程序是不带参数的test()函数
    def test():
    '''
    2*x+1
    :param x:整形数字
    :return: 返回计算结果
    '''
    x=3
    y=2*x+1
    return y
    a=test()
    print(a)

     为什么要使用函数 ? 

    那如果不使用函数会有如下问题:

    1、代码的组织结构不清晰,可读性差
    2、遇到重复的功能只能重复编写实现代码,代码冗余
    3、功能需要扩展时,需要找出所有实现该功能的地方修改之,无法统一管理且维护难度极大 
    所以,如果使用函数,将得到以下好处:

    1.代码重用

     2.保持一致性,易维护

        3.可扩展性

    过程:过程本身也是一个函数,只不过是没有返回值
    def test01():    # test01就是一个过程,因为无返回值
        msg = 'test01'
        print(msg)
    
    
    def test02():    # test02 是一个函数,因为有返回值
        msg = 'test02'
        print(msg)
        return msg
    
    t1 = test01()
    t2 = test02()
    print(t1)        # 结果 None
    print(t2)        # 结果 test02        

    def test03():
    msg = 'test03'
    print(msg)
    return 1,2,3,4,'a',['alex'],{'name':'alex'},None # 返回值可以是一个,也可是多个
    # 结果

    test01
    test02
    test03
    test03
    None
    test02

    (1, 2, 3, 4, 'a', ['alex'], {'name': 'alex'}, None)

    def test01():
        pass
    
    def test02():
        return 0
    
    def test03():
        return 0, 10, 'hello', ['alex', 'lb'], {'WuDaLang': 'lb'}
    
    t1 = test01()
    t2 = test02()
    t3 = test03()
    
    print('from test01 return is [%s]: ' % type(t1), t1)
    print('from test02 return is [%s]: ' % type(t2), t2)
    print('from test03 return is [%s]: ' % type(t3), t3)
    
    #结果
    from test01 return is [<class 'NoneType'>]:  None
    from test02 return is [<class 'int'>]:  0
    from test03 return is [<class 'tuple'>]:  (0, 10, 'hello', ['alex', 'lb'], {'WuDaLang': 'lb'})

    总结:当一个函数/过程没有使用return显示的定义返回值时,python解释器会隐式的返回None,

    所以在python中即便是过程也可以算作函数。

    总结:

    返回值数 = 0,返回None

    返回数值 = 1 ,返回Object

    返回数值 > 1,返回tuple

    函数参数

    1.形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量

    2.实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值。

    3.位置参数和关键字(标准调用:实参与形参位置一一对应;关键字调用:位置无需固定)

    4.默认参数

    5.参数组

    def calc(x,y): #x=2,y=3
        res=x**y
        return res
        # 函数如果碰到return,该函数就的结束了,即使你后面有多个return,也不会执行;如果需要有多个return,需要通过 条件判断的形式进行
        return y
    res=calc(2,3)
    print(res)
    # 形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量,
    # 所以,此时想打印x,y,程序会报错
    print(x)
    print(y)
    # 结果
    NameError: name 'x' is not defined
    def test(x,y,z):#x=1,y=2,z=3
        print(x)
        print(y)
        print(z)
    
    #位置参数,必须一一对应,缺一不行多一也不行
    test(1,2)    # TypeError: test() missing 1 required positional argument: 'z'
    test(1,2,3)  # 1,2,3, 位置一一对应的关系,传值,成就就正常
    
    #关键字参数,无须一一对应,缺一不行多一也不行
    test(y=1,x=3,z=4)
    
    #位置参数一定要在关键字参数左边,不可混合使用
    test(1,y=2,3)#报错, SyntaxError: positional argument follows keyword argument, 位置参数跟在了关键字参数的后面。
    print(test(1,3,y=2))#报错, TypeError: test() got multiple values for argument 'y' ,就是参数y给传了多个参数
    test(1,3,z=2,y=4)#报错,test() got multiple values for argument 'y',就是参数y给传了多个参数
    test(z=2,1,3)#报错,位置参数必须在关键字参数的左边
    test(1,3,z=2)
    # 默认参数
    def handle(x,type='mysql'):
        print(x)
        print(type)
    
    handle('hello')
    # 结果
    hello
    mysql
    
    handle('hello',type='sqlite')    # 默认参数传参写关键字, 
    # 结果
    hello
    sqlite
    
    handle('hello','sqlite')        # 默认参数传参不写关键字
    # 结果
    hello
    sqlite

    # 还有, 比如安装软件, 有些功能默认是安装的,有些功能默认不是安装的
    def install(func1=False,func2=True,func3=True):
    pass
    # 参数组:  两个星** 表示字典字典, 一个星表示*列表
    
    # 一个*后面,最好按照规定就写args,实参的第一个参数就给形参的第一个参数,其他的实参都默认按照列表的方式处理,传给args了
    def test(x,*args):   
        print(x)
        print(args)
    
    # test(1)
    # 结果
    1
    ()
    
    test(1,2,3,4,5)
    # 结果
    1
    (2, 3, 4, 5)
    
    test(1,{'name':'alex'})
    #结果
    1
    ({'name': 'alex'},)
    
    test(1,['x','y','z'])  # 如果列表前没加*, 就表示把列表作为一个整体传给args参数的第一个元素
    # 结果
    # 1
    # (['x', 'y', 'z'],)
    
    test(1,*['x','y','z']) # 如果列表前加*, 就与*args对应起来了,表示把列表的元素遍历一遍,依次赋给args参数
    # 结果
    1
    ('x', 'y', 'z')
    
    test(1,*('x','y','z'))
    # 结果
    1
    ('x', 'y', 'z')
    
    上面示例的实参的传递方式都是按照位置的方式进行的。
    
    下面示例的实参的传递方式按照关键字的方式
    # 两个**后面最好也按照规定就写kwargs,
    def test(x,**kwargs):   
        print(x)
        print(kwargs)
        
    test(1,y=2,z=3)
    #结果
    1
    {'y': 2, 'z': 3}
    
    test(1,1,2,2,2,2,2,y=2,z=3)
    # 结果
    TypeError: test() takes 1 positional argument but 7 were given
    y前面的是按照位置参数的方式传的,必须一一对应,但是位置形参只有一个,实参却传递了7个
    
    test(1,y=2,z=3,z=3)#会报错 :一个参数不能传两个值
    # 结果
    SyntaxError: keyword argument repeated  关键字参数重复了
    
    下面的示例形参表示方法,意味着该函数无所不能,可以接受任意形式的参数
    def test(x,*args,**kwargs): print(x) print(args) print(kwargs)
    test(
    1,1,2,1,1,11,1,x=1,y=2,z=3) #报错 # 结果 TypeError: test() got multiple values for argument 'x' test(1,1,2,1,1,11,1,y=2,z=3) 1 -->给了x (1, 2, 1, 1, 11, 1) -->给了 args {'y': 2, 'z': 3} -->给了 kwargs def test(x,*args,**kwargs): print(x) print(args) print(kwargs,kwargs['z']) test(1,1,2,1,1,11,1,y=2,z=3) # 结果 1 (1, 2, 1, 1, 11, 1) {'y': 2, 'z': 3} 3 def test(x,*args,**kwargs): print(x) print(args) print(kwargs,kwargs.get('y')) test(1,*[1,2,3],**{'y':1}) #结果 1 (1, 2, 3) {'y': 1} 1
  • 相关阅读:
    进程池,线程池,协程,gevent模块,协程实现单线程服务端与多线程客户端通信,IO模型
    线程相关 GIL queue event 死锁与递归锁 信号量l
    生产者消费者模型 线程相关
    进程的开启方式 进程的join方法 进程间的内存隔离 其他相关方法 守护进程 互斥锁
    udp协议 及相关 利用tcp上传文件 socketserver服务
    socket套接字 tcp协议下的粘包处理
    常用模块的完善 random shutil shevle 三流 logging
    day 29 元类
    Django入门
    MySQL多表查询
  • 原文地址:https://www.cnblogs.com/victorm/p/9113355.html
Copyright © 2020-2023  润新知