zoukankan      html  css  js  c++  java
  • 第十一篇 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
  • 相关阅读:
    Spring(十一):Spring配置Bean(四)SpEL
    Java中动态代理方式(使用java.lang.reflect.Proxy实现):
    设计模式(八)静态代理与动态代理模式
    Spring(十):Spring配置Bean(三)Bean的作用域、使用外部属性文件
    如何把本地代码提交到git(码云)、github代码管理项目上
    Spring(九):Spring配置Bean(二)自动装配的模式、Bean之间的关系
    centos7安装mysql5.7
    haproxy(单机)+mysql集群负载均衡
    sql server 用户创建与权限管理
    MySQL之 从复制延迟问题排查
  • 原文地址:https://www.cnblogs.com/victorm/p/9113355.html
Copyright © 2011-2022 走看看