• Python-Day4-函数


    一、函数定义

    函数能提高应用的模块性,和代码的重复利用率。

    1、语法

    def functionname( parameters ):
       "函数_文档字符串"
       function_suite
       return [expression]
    • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()
    • 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
    • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
    • 函数内容以冒号起始,并且缩进。
    • return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。

    2、函数定义

    >>> def hello() :
    ...    print("Hello World!")
    ... 
    >>> hello()
    Hello World!
    

    3、过程定义

    >>> hello()
    Hello World!
    >>> def hello():
    ...     #定义函数
    ...     print ("Hello World!")
    ...     return 0
    ... 
    >>> a = hello()
    Hello World!
    >>> print(a)
    0
    >>> def test():
    ...     #定义过程
    ...     print("This is a girl")
    ... 
    >>> b = test()
    This is a girl
    >>> print(b)
    None
    

    函数和过程,函数比过程多了一个return的返回值。 函数和过程其实在python中没有过多的界限,当有return时,则输出返回值,当没有return,则返回None.

    使用函数的好处:

    • 代码重复利用
    • 可扩展性
    • 保持一致性
    def bian():
        print("便便么么哒")
    def hello():
        print ("Hello World!")
        bian()
    def test():
        print("This is a girl")
        bian()
    a = hello()
    b = test()
    print(a)
    print(b)
    #输出

    Hello World!
    便便么么哒
    This is a girl
    便便么么哒
    None
    None

    二、函数参数及调用

    1、返回值

    return两个作用:

    • 需要用一个变量来接受程序结束后返回的结果
    • 它是作为一个结束符,终止程序运行
    def test():
        print("in the test")
        return 0
        print(test)
    x = test()
    print(x)#没有输出  

    输出:

    in the test
    0

    return 0后面的代码就不执行了,只执行return前面的代码;变量x接受了test()函数结束后的返回结果 。

    return返回值分三种情况:

    • 返回None,没有定义时返回
    • 返回一个值
    • 返回多个值,1个元组(tuple)
    def test():
        print("in the test")
    #返回None def test_1(): print("in the test_1") return 0
    #返回0 def test_2(): print("in the test_2") return 1,"Good",[2,3];{"bianbian":"18岁"}
    #返回多个值 x = test() y = test_1() z = test_2() print(x,y,z) 

    结果:

    in the test
    in the test_1
    in the test_2
    None 0 (1, 'Good', [2, 3], {'bianbian': '18岁'})
    

    2、有参数函数调用

    形参:指的是形式参数,是虚拟的,不占用内存空间,形参单元只有被调用的时才分配内存单元

    实参:指的是实际参数,是一个变量,占用内存空间,数据传递单向,实参传给形参,形参不能传给实参

    def test(x,y):
    #x,y是行参 print(x) print(y) test(1,2)
    #1,2是实参

    输出

    1
    2
    

    3、位置参数

    实际参数和形式参数是一一对应的,如果调换位置,x和y被调用的时,位置也会互换

    def test(x,y):
        print(x) 
        print(y)
    print("-------互换参数前------")
    test(1,2)
    print("-------互换参数后------")
    test(2,1)
    

     多一个或者少一个参数,都是不行的

    def test(x,y):
        print(x)
        print(y)
    print("-------多一个参数------")
    test(2,1,8)
    print("-------少一个参数------")
    test(2)
    Traceback (most recent call last):
      File "/Users/bianbian/PycharmProjects/test/test 4.py", line 5, in <module>
        test(2,1,8)
    TypeError: test() takes 2 positional arguments but 3 were given
    

    4、关键字参数  

    关键字传参不需要一一对应,只需要你指定你的哪个形参调用哪一个实参即可  

    def test(x,y):
        print(x)
        print(y)
    print("-------互换参数前------")
    test(x=1,y=2)
    print("-------互换参数后------")
    test(y=2,x=1)
    

     结果:

    -------互换参数前------
    1
    2
    -------互换参数后------
    1
    2
    

      ①位置参数在前,关键字参数在后

    def test(x,y):
        print(x)
        print(y)
    test(1,y=2)
    结果:
    1
    2
    

    下面这样写会报错,报错的原因是:实参1已传给形参x,x=2又传了一次,所以报错。

    def test(x,y):
        print(x)
        print(y)
    test(1,x=2)
    Traceback (most recent call last):
      File "/Users/bianbian/PycharmProjects/test/test 4.py", line 4, in <module>
        test(1,x=2)
    TypeError: test() got multiple values for argument 'x'
    

     ②关键字在前,位置参数在后  

    下面四个例子,前两个运行报错,后两个可以正常运行,我们可以得出一个结论:关键字参数是不能写在位置参数前面的。

    def test(x,y):
        print(x)
        print(y)
    test(y=2,1)
        test(y=2,1)
                ^
    SyntaxError: positional argument follows keyword argument
    
    def test(x,y):
        print(x)
        print(y)
    test(1,y=2,3)
        test(1,y=2,3)
                  ^
    SyntaxError: positional argument follows keyword argument
    
    def test(x,y,z):
    print(x)
    print(y)
    print(z)
    test(1,2,z=3)
    结果: 1 2 3 
    def test(x,y,z):
        print(x)
        print(y)
        print(z)
    test(1,y=2,z=3)
    结果:
    1
    2
    3
    

     总结:

    1. 既有关键字,又有位置参数时,是按位置参数的顺序传参
    2. 关键字参数不能写在位置参数前面

     

    三、非固定参数

    1、默认参数

    默认参数指,在传参之前,先给参数制定一个默认的值。当我们调用函数时,默认参数是非必须传递的。

    def test(x,y=2):
        print(x)
        print(y)
    print("-------1--------")
    test(1)#没有给默认参数传值
    print("-------2--------")
    test(1,y=3)#给默认参数传关键字参数
    print("-------3--------")
    test(1,3)#给默认参数传位置参数
    

     结果:

    -------1--------
    1
    2
    -------2--------
    1
    3
    -------3--------
    1
    3
    

    默认参数用途:

    • 安装默认软件(def test(x,soft=True))
    • 传递一下默认的值(定义mysql的默认端口号:def count(host,port=3306))????

    2、参数组

      我们可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述参数不同,声明时不会命名。基本语法如下:

    def functionname([formal_args,] *var_args_tuple ):
       "函数_文档字符串"
       function_suite
       return [expression]
    

     加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。

     有以下两种传参方式:
    1. 非固定位置参数传参(*args)
    2. 非固定关键字传参(**kwargs)

    2.1 非固定位置参数传参(*args)

    (*args)接收N个位置参数,转换成元组的形式

    (1)语法如下:

    def test(*args):
    #形参以*开头,args参数名可自行定义,建议按照规范定义成args
        print(args)
    test(1,2,3,4,5,6,7,8,8)
    #输入多个位置参数
    结果:
    (1, 2, 3, 4, 5, 6, 7, 8, 8)
    

    (2)传入列表:

    def test(*args):
        print(args)
    print("-------什么都不传------")
    test()
    print("-------在传入的列表的前面加*,输出的args的元组形式------")
    test(*[1,2,3,4,5])
    print("-------在传入的列表的前面不加*,列表被当做单个位置参数,输出的结果是元组中的一个元素------")
    test([1,2,3,4,5])
    结果:
    -------什么都不传------
    ()
    -------在传入的列表的前面加*,输出的args的元组形式------
    (1, 2, 3, 4, 5)
    -------在传入的列表的前面不加*,列表被当做单个位置参数,输出的结果是元组中的一个元素------
    ([1, 2, 3, 4, 5],)
    

    (3)位置参数和非固定位置参数 

    def test(x,*args):
        print(x)
        print(args)
    test(1,2,3,4,5,6)
    结果:
    1
    (2, 3, 4, 5, 6)
    

    第1个参数,被当做位置参数,剩下的被当做非固定位置参数。 

    (4)关键字和非固定位置参数

    def test(x,*args):
        print(x)
        print(args)
    test(x=1,2,3,4,5,6)
    结果:
        test(x=1,2,3,4,5,6)
                ^
    SyntaxError: positional argument follows keyword argument
    

    因为x=1是关键字参数,*args是位置参数,而关键字参数不能再位置参数前面的,所以报错。

    2.2 非固定关键字传参(**kwargs)

    (**kwargs)把N个关键字参数,转换成字典形式。

    (1)语法:

    def test(**kwargs):
        # #形参以**开头,kwargs参数名可自己定义,建议按照规范定义成kwargs
         print(kwargs)
    test(name="bianbian",sex="girl",age=18)
    #传入多个关键字参数
    结果:
    {'name': 'bianbian', 'sex': 'girl', 'age': 18}
    

     多个关键字参数转换成字典

    (2)传入字典

    def test(**kwargs):
         print(kwargs)
    test(**{'name': 'bianbian', 'sex': 'girl', 'age': 18})
    结果:
    {'name': 'bianbian', 'sex': 'girl', 'age': 18}
    

    传入字典时,一定要在字典前面加**,否则就会报错

    def test(**kwargs):
         print(kwargs)
    test({'name': 'bianbian', 'sex': 'girl', 'age': 18})
    结果:
    Traceback (most recent call last):
        test({'name': 'bianbian', 'sex': 'girl', 'age': 18})
    TypeError: test() takes 0 positional arguments but 1 was given
    

    因为传入的字典被当做位置参数,所以被报类型错误,非固定关键字传字典,一定要加**  

    (3)配合位置参数使用

    def test(name, **kwargs):
        print(name)
        print(kwargs)
    
    print("------1个位置参数-----")
    test("便便")
    print("------1个位置参数,两个关键字参数------")
    test("便便", age=18, sex="girl")
    print("------3个关键字参数------")
    test(name="bianbian", age=18, sex="girl")
    结果:
    ------1个位置参数-----
    便便  #输出1个位置参数
    {}  #没有输入关键字参数,所以输出空字典
    ------1个位置参数,两个关键字参数------
    便便 #第1个位置参数
    {'age': 18, 'sex': 'girl'}  #剩下关键字参数,转换成1个字典
    ------3个关键字参数------
    bianbian  #第1个关键字参数
    {'age': 18, 'sex': 'girl'}  #剩下的关键字参数,转换成1个字典
    

     (4)位置参数、关键字和非固定关键字参数

    如果遇到一个关键字传参和非固定关键字传参,

    关键字参数

    前后放的位置是不影响传参的,但是我们一般还是按顺序来。

    def test(name,age=18,**kwargs):
        print(name)
        print(age)
        print(kwargs)
    
    print("------1-----")
    test("便便", age=18, sex="girl")
    print("------2-----")
    test("便便", 18, sex="girl",love="peng")
    print("------3------")
    test("便便",sex="girl",love="peng",age=18)
    

      结果:

    ------1-----
    便便
    18  #不传,显示默认参数
    {'sex': 'girl'}
    ------2-----
    便便
    18 #传位置参数
    {'sex': 'girl', 'love': 'peng'}
    ------3------
    便便
    18 #关键字参数,放在前后并没有影响
    {'sex': 'girl', 'love': 'peng'}
    

    (5)位置参数、关键字参数、非固定位置参数和非固定关键字参数

    def test(name,age=18,*args,**kwargs):
        print(name)
        print(age)
        print(args)
        print(kwargs)
    print("------第一种传参-----")
    test("便便",18,1,2,3,4, sex="girl",love="peng")
    print("------第二种传参-----")
    test("便便",18,*[1,2,3,4],**{'sex':"girl",'love':"peng"})
    

     结果:

    ------第一种传参-----
    便便 #传name位置参数
    18  #给age传位置参数
    (1, 2, 3, 4)  #非固定位置参数,以转换成元组
    {'sex': 'girl', 'love': 'peng'} # 非固定关键字参数,转换成字典
    ------第二种传参-----
    便便
    18
    (1, 2, 3, 4) #以列表的形式传入,在列表前加*
    {'sex': 'girl', 'love': 'peng'} #以字典的形式传入,在字典前加**
    

     下面两种传参方法是不可以的

    def test(name,age=18,*args,**kwargs):
        print(name)
        print(age)
        print(args)
        print(kwargs)
    test("便便",age=18,1,2,3,4,sex="girl",love="peng")
    结果:
        test("便便",age=18,1,2,3,4,sex="girl",love="peng")
                            ^
    SyntaxError: positional argument follows keyword argument
    

     因为age=18是关键字参数,而后面的*args是非固定位置参数,所以不管*args传入几个参数,它的本质都是位置参数,上面我们提到关键字参数是不能再位置参数的前面,所以报错了。

    def test(name,age=18,*args,**kwargs):
        print(name)
        print(age)
        print(args)
        print(kwargs)
    #test1("便便",age=18,1,2,3,4,sex="girl",love="peng")
    test2("便便",18,sex="girl",love="peng",1,2,3,4)
    结果:
        test2("便便",18,sex="girl",love="peng",1,2,3,4)
                                                ^
    SyntaxError: positional argument follows keyword argument
    

    这样也是不可以的。

    非固定关键字参数,本质也是关键字参数,是不能放在非固定位置参数的前面的。

    四、总结 

    1. 参数分为位置参数、关键字参数、默认参数、非固定位置参数和非固定关键字参数
    2. 位置参数之前传参,位置是不能调换的,多一个或者少一个参数都是不可以的。
    3. 关键字参数是不能放在位置参数前面的。
    4. 函数传参的位置一次是,位置参数,默认参数、非固定位置参数、非固定关键字参数(def test(name,age=18,*args,**kwargs))
    5. 关键字传参,可以不用考虑位置的前后问题
     
     

     

     

     

      

     

     

     

      

      

      

     

     

      

      

      

  • 相关阅读:
    CSS 3 中的多列属性
    CSS3 3D转换
    CC3中的2D转换
    ubuntu sudo: pip:找不到命令
    ubuntu 下更新pip后发生 ImportError: cannot import name 'main'的问题解决
    ubuntu 安装pip
    gradle下载
    L0,L1,L2正则化浅析
    安装使用离线版本的维基百科(Wikipedia)
    Linux中CPU亲和性(affinity)
  • 原文地址:https://www.cnblogs.com/bianfengjie/p/10741669.html
Copyright © 2020-2023  润新知