• Python函数参数的五种类型


    之前项目需求,需要通过反射获取函数的参数,python中可以通过函数签名(signature)来实现。

    首先需要了解函数参数的类型,Python的参数类型一共有5种:POSITIONAL_OR_KEYWORD、VAR_POSITIONAL、VAR_KEYWORD、KEYWORD_ONLY、POSITIONAL_ONLY

    其中 POSITIONAL_OR_KEYWORD、VAR_POSITIONAL、VAR_KEYWORD、KEYWORD_ONLY 比较常用

    参数类型为VAR_POSITIONAL时,即*args参数,只能通过位置传值,如

    def say_hello(*args):
        print('hello {0}'.format(args))
    
    # 通过位置传值
    say_hello('jack', 'tom')

    参数类型为VAR_KEYWORD,即 **kwargs参数,只能通过关键字传值,如

    def func_b(**kwargs):
        print(kwargs)
    
    # 通过关键字传值
    func_b(a=1, b=2)

    参数的类型为POSITIONAL_OR_KEYWORD时,说明此参数前面没有VAR_POSITIONAL类型的参数,可以通过位置或关键字传值,如

    def say_hello(name):
        print('hello {0}'.format(name))
    
    # 通过位置传值
    say_hello('jack')
    # 通过关键字传值
    say_hello(name='tom')

    参数类型为KEYWORD_ONLY时,说明此参数前面存在VAR_POSITIONAL类型的参数,只能通过关键字传值,如

    def func_b(*args, a, b):
        print(args, a, b)
    
    # 只能通过关键字传值
    func_b('test', a=1, b=2)

    比较特别的是POSITIONAL_ONLY,只能通过位置传值的参数。Python并没有明确的语法去定义一个只能通过位置传值的函数参数,但是在很多内置和扩展模块的函数会接受这种类型的参数。

    实际获取函数参数时,需要用到inspect模块,通过这个模块的signature方法获取函数签名。

    import inspect
    
    
    def func_a(arg_a, *args, arg_b='hello', **kwargs):
        print(arg_a, arg_b, args, kwargs)
    
    
    if __name__ == '__main__':
    
        # 获取函数签名
        func_signature = inspect.signature(func_a)
        func_args = []
        # 获取函数所有参数
        for k, v in func_signature.parameters.items():
            # 获取函数参数后,需要判断参数类型
            # 当kind为 POSITIONAL_OR_KEYWORD,说明在这个参数之前没有任何类似*args的参数,那这个函数可以通过参数位置或者参数关键字进行调用
            # 这两种参数要另外做判断
            if str(v.kind) in ('POSITIONAL_OR_KEYWORD', 'KEYWORD_ONLY'):
                # 通过v.default可以获取到参数的默认值
                # 如果参数没有默认值,则default的值为:class inspect_empty
                # 所以通过v.default的__name__ 来判断是不是_empty 如果是_empty代表没有默认值
                # 同时,因为类本身是type类的实例,所以使用isinstance判断是不是type类的实例
                if isinstance(v.default, type) and v.default.__name__ == '_empty':
                    func_args.append({k: None})
                else:
                    func_args.append({k: v.default})
            # 当kind为 VAR_POSITIONAL时,说明参数是类似*args
            elif str(v.kind) == 'VAR_POSITIONAL':
                args_list = []
                func_args.append(args_list)
            # 当kind为 VAR_KEYWORD时,说明参数是类似**kwargs
            elif str(v.kind) == 'VAR_KEYWORD':
                args_dict = {}
                func_args.append(args_dict)
    
        print(func_args)
  • 相关阅读:
    (22)C#windows打包部署
    (2)OLEDB数据库操作
    (5)C#工具箱-数据
    (21)C#VS快捷键
    (1)OracleClient数据库操作(淘汰)
    (4)C#工具箱-菜单和工具栏
    (3)C#工具箱-容器
    (2)C#工具箱-公共控件2
    (9)oracle 表的基本查询
    企鹅
  • 原文地址:https://www.cnblogs.com/blackmatrix/p/6673220.html
Copyright © 2020-2023  润新知