动态获取函数的参数

之前项目需求,需要动态的获取函数的参数,查阅一些资料后,发现可以通过函数签名(signature)来实现,记录下做个备忘。

首先需要了解函数参数的类型,目前常用的参数类型主要有4种:POSITIONAL_OR_KEYWORD、VAR_POSITIONAL、VAR_KEYWORD、KEYWORD_ONLY

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

def say_hello(*args):
    print(‘hello {0}‘.format(args))

# 通过位置传值
say_hello(‘jack‘, ‘tom‘)

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

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)

实际获取函数参数时,需要用到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)
时间: 2024-11-06 16:07:33

动态获取函数的参数的相关文章

能否在函数内动态获取函数名称 ?(亲测,居然真的可以)

C++ 可以用宏定义 __FUNCTION__ 或__func__ 获取所在的函数.方便调试. #define LOG(fmt, args...) printf("%s:"fmt,__FUNCTION__,##args) Delphi是否也能呢 ?Delphi 如何动态获取函数名称,而不是每个函数log都打一遍函数名. C++ Builder 是否像 C++ 也提供这种支持 ? 可以通过一些调试信息获取,请研究jclDebug.ProcByLevel 32 位系统不错.64 位系统的获

php动态获取函数参数

PHP 在用户自定义函数中支持可变数量的参数列表.其实很简单,只需使用 func_num_args() , func_get_arg() ,和 func_get_args()  函数即可. 可变参数并不需要特别的语法,参数列表仍按函数定义的方式传递给函数,并按通常的方式使用这些参数. 1.func_num_args — 返回传入函数的参数总个数 int func_num_args ( void ) 示例 <?php function demo () { $numargs = func_num_a

JS模式--装饰者模式(用AOP动态改变函数的参数)

Function.prototype.before = function (beforefn) { var _self = this; return function () { beforefn.apply(this, arguments); return _self.apply(this, arguments); }; }; var func = function (param) { console.log(param); }; func =func.before( function (par

C#在函数内部获取函数的参数

foreach (var parameter in typeof(类名).GetMethod("方法名").GetParameters()) { Console.WriteLine(parameter.ParameterType);//参数类型 Console.WriteLine(parameter.Position);//参数位置 Console.WriteLine(parameter.Name);//参数名 }

js 获取函数的所有参数名

具体思路: 利用Function.toString()方法,获取到函数的源码,再利用正则匹配获取到参数名字. 实现代码(代码基于ES6): // 获取函数的参数名 function getParameterName(fn) { if(typeof fn !== 'object' && typeof fn !== 'function' ) return; const COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; const DEFAULT_PA

使用Mono Cecil 动态获取运行时数据 (Atribute形式 进行注入) -摘自网络

目录 一:普通写法 二:注入定义 三:Weave函数 四:参数构造 五:业务编写 六:注入调用 一:普通写法 1 2 3 4 public static string GetPoint(int x, int y)  {     var value=x; } 哇 好简单啊.其实动态获取和我们普通这样写代码是一样的,我们把要注入的代码,生成一个接收的变量就可以了. 就像上面value 一样接收,然后传递给我们自己函数就可以了. 二 :注入定义 public class WeaveService :

日志系统实战(二)-AOP动态获取运行时数据

介绍 这篇距上一篇已经拖3个月之久了,批评自己下. 通过前面一篇介绍.我们通过mono反射代码,可以拿出编译好的静态数据.例如方法参数信息之类的.但实际情况是:我更需要运行时的数据,就是用户输入等外界的动态数据. 既然是动态的,那就是未知的.我们怎么通过提前注入的代码获取呢? 其实这是一个思路的问题,下面我们具体细看下. 实现 一 普通写法 public static string GetPoint(int x, int y) { var value=x; } 哇 好简单啊.其实动态获取和我们普

iwpriv工具通过ioctl动态获取相应无线网卡驱动的private_args所有扩展参数

iwpriv工具通过ioctl动态获取相应无线网卡驱动的private_args所有扩展参数 iwpriv是处理下面的wlan_private_args的所有扩展命令,iwpriv的实现上,是这样的,=>main=>set_private=>iw_get_priv_info获取wireless网卡所能处理的所有wlan_private_args类型. dev_ioctl=>wext_handle_ioctl=>wireless_process_ioctl    if (cmd

JavaScript函数之实际参数对象(arguments) / callee属性 / caller属性 / 递归调用 / 获取函数名称的方法

函数的作用域:调用对象 JavaScript中函数的主体是在局部作用域中执行的,该作用域不同于全局作用域.这个新的作用域是通过将调用对象添加到作用域链的头部而创建的(没怎么理解这句话,有理解的亲可以留言告诉我, 谢谢).因为调用对象是作用域链的一部分,所以在函数体内可以把这个对象属性作为变量来访问. 调用对象的属性包括:用var声明的局部变量,函数形参,还有一种特殊的属性arguments 函数的实际参数:实际参数对象 arguments对象,用来引用实际参数对象.函数的arguments对象并