zoukankan      html  css  js  c++  java
  • Python 函数的参数

    python 函数的参数可分为位置参数、缺省参数、可变参数和关键字参数。其中可变参数和关键字参数又可以进行拆包。

    位置参数

    看下面程序:

        def fun1(a, b):
            print("a -- " + str(a))
            print("b -- " + str(b))
            return a + b
    
        print(fun1(2, 3))
    

    显然,程序结果:

        a ---- 2
        b ---- 3
        5
    

    这里的函数 fun1 中的参数 a 和 b 就是位置参数。位置参数在调用时,必须给到具体值。

    缺省参数

    看下面的代码:

        def fun2(a, b, c=0):
            print("a -- " + str(a))
            print("b -- " + str(b))
            print("c -- " + str(c))
            return a + b + c
    
        print(fun2(2, 3))
        print(fun2(2, 3, 4))
    

    程序输出结果:

        a -- 2
        b -- 3
        c -- 0
        5
        a -- 2
        b -- 3
        c -- 4
        9
    

    这里函数 fun2 中,有三个参数,其中 a 和 b 是位置参数, c 即是一个缺省参数。声明函数 fun2 时指定了参数 c=0 ,表示参数 c 的默认值是 0 ,上面程序中两次在调用 fun2 时,分别传入了两个参数和三个参数。我们看到,在传入两个参数时,a 和 b 的值分别是传入的 2 和 3,其中 c 的值为默认值 0 ,在传入三个参数时,a, b 和 c 值分别是传入的 2, 3, 4 。
    很好理解,在函数定义的时候,给参数赋了一个默认值,这样的参数就叫缺省参数,也叫默认参数。
    假设有多个缺省参数,而我只传入了部分缺省参数会是怎样的情况?看下面的程序:

        def fun2(a, b, c=0, d=0):
            print("a -- " + str(a))
            print("b -- " + str(b))
            print("c -- " + str(c))
            print("d -- " + str(d))
            return a + b + c + d
    
        print(fun2(2, 3, 4))
    

    程序执行结果如下:

        a -- 2
        b -- 3
        c -- 4
        d -- 0
        9
    

    说明,前面的位置参数是必须要传入的,c 的值是 4 ,而 d 的值是默认值 0 ,这说明,传入的部分缺省参数会按顺序赋值。如果偏要将 4 赋给 d ,而 c 用默认参数呢,则用下面方式调用函数即可: print(fun2(2, 3, d=4)) 程序结果:

        a -- 2
        b -- 3
        c -- 0
        d -- 4
        9
    

    不止是缺省参数,位置参数也可以在调用函数时,也可以指定具体的值赋给哪个参数。

    值得注意的是:定义函数时缺省参数要放在位置参数后面,如果向下面这样定义:

        def fun2(a, b=0, c):
            return a + b + c
    

    则会报错:SyntaxError: non-default argument follows default argument

    熟悉 java、C# 或者 C++ 等语言的应该知道“重载方法”的概念。参数列表不相同,包括参数的类型不相同和参数的个数不相同。在python中,用缺省参数,正好可以实现重载类似的效果。

    可变参数(不定长参数)

    在Python函数中,还可以定义可变参数,也叫不定长参数。顾名思义,可变参数就是传入的参数个数是可变的,写法为,在参数前面加上一个 * ,类似于 java 中的不定长参数。不同的是,java中不定长参数,以数组形式存储,在python中,可变参数则是一个元组。看下面的程序:

        def fun3(a, *b):
            print(type(a))
            print(a)
            print(type(b))
            print(b)
    
        fun3(1, 2, 3, 4, 5)
    

    输出结果如下:

        <class 'int'>
        1
        <class 'tuple'>
        (2, 3, 4, 5)
    

    程序中,函数 fun3 的参数 a 是一个 int 型,后面 *b 即为可变参数,在调用时,可以根据需要传入不同个数的参数,除去 a 之后,剩余所有的参数,都添加到一个元组中。

    看下面的调用: fun3(1, 2, (3, 4, 5), [6, 7], {'x': 8, 'y': 9}, 10, 11)
    输出结果如下:

        <class 'int'>
        1
        <class 'tuple'>
        (2, (3, 4, 5), [6, 7], {'x': 8, 'y': 9}, 10, 11)
    

    结果显示很明确了,即便我传入列表,元组,字典类型的参数,也会被当做元组的元素,添加进去。 约定俗成,函数中的可变参数一般用 *args 来表示。

    关键字参数

    最后说说 python 的关键字参数。python 关键字参数是在参数前面加上 ** ,和可变参数有点类似,区别在于,关键字参数是以字典形式存储。调用的时候也有区别,看下面的程序:

        def fun4(a, *b, **c):
            print(type(c))
            print(a)
            print(b)
            print(c)
    
        fun4(1, 2, 3, 4, 5, x=6, y=7)
    

    程序结果:

        <class 'dict'>
        1
        (2, 3, 4, 5)
        {'x': 6, 'y': 7}
    

    结果显示,参数 C 的类型是 dict 字典。在调用时,需要按照 key = value 的形式传入关键字参数。约定俗成,关键字参数一般用 **kwargs 来表示。按照上面的写法,我们调用函数时可以随意传入关键字参数,有时候,我们需要限定关键字参数的 'key' ,这样我们可以使用命名关键字参数。比如,上面的程序,我在调用时关键字参数,传入了 'x' 和 'y',事实上,我想的话,还可以传入更多的参数 ,用命名关键字参数,则可以限定,只传入 'x' 和 'y' ,程序如下:

        def fun5(a, *, x, y):
            print(a)
            print(x)
            print(y)
    
    
        fun5(1, x=2, y=3)
    

    输出结果:

        1
        2
        3
    

    即用一个 *,,后面跟上指定的参数。这样,你如果多传,或者少穿关键字参数,都是不可以的。

    可变参数和关键字参数拆包

    再回头看前面的例子:

        def fun3(a, *b):
            print(type(a))
            print(a)
            print(type(b))
            print(b)
    
        fun3(1, 2, 3, 4, 5)
    

    执行 fun3(1, 2, (3, 4, 5), [6, 7], {'x': 8, 'y': 9}, 10, 11)
    输出结果如下:

        <class 'int'>
        1
        <class 'tuple'>
        (2, (3, 4, 5), [6, 7], {'x': 8, 'y': 9}, 10, 11)
    

    这里,传入参数的 (3,4,5) 和 [6,7] 和 {'x': 8, 'y': 9} 都被当作元组里面的元素了。下面在调用时,参数前面添加一个 * ,如下:
    fun3(1, 2, *(3, 4, 5), *[6, 7], *{'x': 8, 'y': 9}, 10, 11)

    结果如下:

        <class 'int'>
        1
        <class 'tuple'>
        (2, 3, 4, 5, 6, 7, 'x', 'y', 12, 13)
    

    看结果,在列表或者元组参数前面添加 * 之后,却反而被拆开成单个元素,作为元组的元素。而字典,只是把它的 'key' 拆成单个元素。这就是可变参数的拆包。一般,可变参数的拆包我们只针对元组和列表,不针对字典。
    同样,对于含有关键字参数的函数,也可对传入的参数进行拆包,看下面这个函数:

        def fun6(**kwargs):
            print(kwargs)
    

    下面我调用函数 fun6({'x': 1, 'y': 2}) ,这时候,程序会报错

    因为,关键字参数,在调用的时候传参,需要按照 key = value 的形式传入。而我现在传入一个字典,会被当做一个整体,作为一个位置参数传入。如果以下面这种方式
    fun6(**{'x': 1, 'y': 2})
    调用,则可行,结果如下:

        {'x': 1, 'y': 2}
    

    即通过 ** 将字典拆成了 'x'=1 , 'y'=2 的形式。这就是关键字参数的拆包。

  • 相关阅读:
    ajax(ajax开发)
    gnuplot常用技巧
    Gunplot 命令大全
    程序员的绘图利器 — Gnuplot
    什么是 gnuplot
    QT正则表达式---针对IP地址
    JSP实现分页功能
    java.lang.OutOfMemoryError: Java heap space错误及处理办法
    getInitParameter()
    C/S软件的自动升级部署
  • 原文地址:https://www.cnblogs.com/joy99/p/8870188.html
Copyright © 2011-2022 走看看