Python中如何获取传入函数的目标函数名及参数?
在Python中获取最后调用的函数名称及参数的方案
嗨,我来帮你搞定这个问题~首先得先指出你示例代码里的几个小细节问题,还有一个容易踩的坑:
- Python3里
print a要改成print(a)哦,不然会报错; if __name__ = "__main__"这里是双等号==,单等号是赋值,会触发语法错误;- 最关键的是:你现在写的
B(A(a))其实是先执行了A(a),然后把它的返回值(也就是None,因为A函数没有return语句)传给B,这时候B根本拿不到A这个函数和它的参数a哦。
所以我们得调整思路,下面给你几种可行的实现方案,你可以根据自己的需求选:
方案一:主动传递函数和参数给B
这种方式最直接,把函数本身和它的参数分开传给B,在B里记录信息并执行函数:
def A(a): print(a) def B(func, *args, **kwargs): # 获取函数名称 func_name = func.__name__ # 格式化位置参数 args_str = ", ".join(repr(arg) for arg in args) # 格式化关键字参数 kwargs_str = "" if kwargs: kwargs_str = ", ".join(f"{k}={repr(v)}" for k, v in kwargs.items()) # 拼接成目标格式的字符串 params_str = "" if args_str and kwargs_str: params_str = f"{args_str}, {kwargs_str}" else: params_str = args_str or kwargs_str target_info = f"{func_name}({params_str})" print("获取到的目标信息:", target_info) # 执行原函数 return func(*args, **kwargs) if __name__ == "__main__": # 这里直接传A和它的参数,而不是A(a) B(A, "hello world")
运行后会输出:
获取到的目标信息: A('hello world') hello world
方案二:用装饰器包装函数,支持B(A(a))的调用方式
如果你不想改调用形式,想用B(A(a))这种写法,可以给A加个装饰器,让它返回包含函数和参数的信息对象,再让B解析这个对象:
from functools import wraps # 装饰器:让函数返回包含自身和参数的信息 def trackable(func): @wraps(func) def wrapper(*args, **kwargs): return { "func": func, "args": args, "kwargs": kwargs } return wrapper @trackable def A(a): print(a) def B(func_info): # 从信息对象里取出函数和参数 func = func_info["func"] args = func_info["args"] kwargs = func_info["kwargs"] # 拼接目标信息 func_name = func.__name__ args_str = ", ".join(repr(arg) for arg in args) kwargs_str = ", ".join(f"{k}={repr(v)}" for k, v in kwargs.items()) if kwargs else "" params_str = f"{args_str}, {kwargs_str}" if args_str and kwargs_str else args_str or kwargs_str target_info = f"{func_name}({params_str})" print("获取到的目标信息:", target_info) # 执行原函数 return func(*args, **kwargs) if __name__ == "__main__": # 现在可以用B(A(a))的形式调用啦 B(A("hello world"))
运行效果和方案一完全一致。
方案三:用inspect模块查看调用栈
如果是想获取代码中实际调用的语句(比如A("test")这种原始写法),可以用Python的inspect模块来读取调用栈信息:
import inspect def A(a): print(a) # 获取调用栈:inspect.stack()[0]是当前函数,[1]是调用当前函数的上层 caller_frame = inspect.stack()[1] # 提取调用的代码行 call_statement = caller_frame.code_context[0].strip() print("最后调用的函数及参数:", call_statement) def B(func): # 在B里获取调用B的语句 caller_frame = inspect.stack()[1] call_statement = caller_frame.code_context[0].strip() print("最后调用的函数及参数:", call_statement) if __name__ == "__main__": A("test") # 调用B的时候,会输出B(A) B(A)
运行后输出:
test 最后调用的函数及参数: A("test") 最后调用的函数及参数: B(A)
这种方法适合需要获取原始调用代码的场景,但要注意:如果调用语句有多行或者被压缩,可能会获取不完整。
内容的提问来源于stack exchange,提问作者wzhang
相关产品推荐
相关产品推荐

