zoukankan      html  css  js  c++  java
  • Day 19:Python 函数五类参数

    Python 五类参数

    • 默认参数
    • 位置参数(positional argument)
    • 关键字参数(keyword argument)
    • 可变位置参数
    • 可变关键字参数

    默认参数很好理解,如果不传参给那个参数的话,就使用定义时候设置的默认值:

    def f(a=0):
        print(f'a:{a}')
    #两种调用方式
    f()
    f(1)
    
    output:
    0
    1

      如果一个函数有一个参数a,根据调用函数f时的传参方式不同,a即可能是位置参数,也可能是关键字参数。

    def f(a):
      print(f'a:{a}')

    位置参数的调用

    f(1)
    
    a:1

    关键字参数的调用

    f(a=1)
    
    a:1

      

      如果有一个函数以如下方式定义:

    def f(a, *b, **c):
        print(f'a:{a},b:{b},c:{c}')

    函数 f 的参数稍显复杂,但也是最常用的函数参数定义结构。

    • 出现带一个星号的参数 b,这是可变位置参数,被解析为元组
    • 两个星号的参数 c,这是可变关键字参数,被解析为字典
    f(1,2,3,w=4,h=5)
    f(1,2,w=4)
    
    output:
    a:1,b:(2, 3),c:{'w': 4, 'h': 5}
    a:1,b:(2,),c:{'w': 4}

    可变表示函数被赋值的变量个数是变化的。

    查看参数

    借助 Python 的 inspect 模块查看参数的类型: 

    from inspect import signature
    def f(a,*b):
        print(f'a:{a},b:{b}')
    
    for name,val in signature(f).parameters.items():
        print(name,val.kind)
    
    output:
    a POSITIONAL_OR_KEYWORD
    b VAR_POSITIONAL

    参数 a 既可能是位置参数,也可能是关键字参数。参数 b 为可变位置参数。

    from inspect import signature
    def f(*,a,**b):
      print(f'a:{a},b:{b}')
    for name,val in signature(f).parameters.items():
        print(name,val.kind)
    
    output:
    a KEYWORD_ONLY
    b VAR_KEYWORD

    a 只可能为 KEYWORD_ONLY 关键字参数。就是因为定义a之前定义了一个*号,划重点,*号后面的参数只可能是关键字参数,不可能是位置参数

    传递规则

    Python函数定义时有一定的约束规则。如果不了解这些规则,函数调用时,可能会出现各种各样的调用异常。

    常见的异常有以下六类:

    • SyntaxError: positional argument follows keyword argument,位置参数位于关键字参数后面
    • TypeError: f() missing 1 required keyword-only argument: 'b',必须传递的关键字参数缺失
    • SyntaxError: keyword argument repeated,关键字参数重复
    • TypeError: f() missing 1 required positional argument: 'b',必须传递的位置参数缺失
    • TypeError: f() got an unexpected keyword argument 'a',没有这个关键字参数
    • TypeError: f() takes 0 positional arguments but 1 was given,不需要位置参数但却传递 1 个

    为了避免这些错误,只要摸索正确的使用规则就好了。

    规则 1:不带默认值的位置参数缺一不可
    规则 2:关键字参数(通过键=值传参的)必须在位置参数右边
    def f(a,b):
        pass
    
    f(a=1,20)
    
    output:
      File "<ipython-input-21-bdc62c937217>", line 4
        f(a=1,20)
             ^
    SyntaxError: positional argument follows keyword argument
    规则 3:对同一个形参不能重复传值
    def f(a,**b):
        passf(1,width=20.,width=30.)
    
    SyntaxError: keyword argument repeated
    规则 4:默认参数的定义应该在位置形参右面,默认参数通常应该定义成不可变类型。
    规则 5:可变位置参数不能传入关键字参数
    def f(*a):
      print(a)
    f(1)
    f(1,2,3)
    f(1,'ss',[1,2,3],4)
    #可变位置参数不能传入关键字参数
    f(a=1)
    
    output:
    (1,)
    (1, 2, 3)
    (1, 'ss', [1, 2, 3], 4)
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-24-e485cc7c8886> in <module>()
          5 f(1,'ss',[1,2,3],4)
          6 #可变位置参数不能传入关键字参数
    ----> 7 f(a=1)
    
    TypeError: f() got an unexpected keyword argument 'a'
    规则 6:可变关键字参数不能传入位置参数
    def f(**a):
      print(a)
    
    f(a=1)
    f(a=1,b=2,width=3,lst=['a',['ssd',2,'s']])
    f(1)
    
    output:
    {'a': 1}
    {'a': 1, 'b': 2, 'width': 3, 'lst': ['a', ['ssd', 2, 's']]}
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-27-11c232a4bc21> in <module>()
          4 f(a=1)
          5 f(a=1,b=2,width=3,lst=['a',['ssd',2,'s']])
    ----> 6 f(1)
    
    TypeError: f() takes 0 positional arguments but 1 was given
  • 相关阅读:
    3D Slicer 体系结构2
    3D Slicer 体系结构1
    3D Slicer FAQ-3
    3D Slicer FAQ-2
    3D Slicer FAQ-1
    3D Slicer 编译、调试、规范化的开发
    3D Slicer 开发者必晓ABC
    3D Slicer 模块管理(二)场景视图、体数据、体绘制
    3D Slicer 模块管理(一)颜色、DCM、数据、模型、注释
    3D Slicer 数据与帮助
  • 原文地址:https://www.cnblogs.com/PiaYie/p/14981658.html
Copyright © 2011-2022 走看看