gpt4 book ai didi

python - 获取 Python 函数的调用字符串,如在命令行中键入的那样

转载 作者:行者123 更新时间:2023-12-04 17:37:44 24 4
gpt4 key购买 nike

我想使用内省(introspection)从函数本身存储为函数调用键入的确切字符串(我不能/不想破解命令行解释器——因此,例如从 readline 或任何不是我要找的东西)。

假设,如果用户输入:

>>> myfunc('a', 'b', 1, mykwarg='hello')

我想获取调用字符串(即 myfunc('a', 'b', 1, mykwarg='hello'))来自 myfunc 中的代码。

我可以制作这样的东西:

def myfunc(a,b,c,mykwarg=None):
frame = inspect.currentframe()
sig = inspect.signature(myfunc)
args = []
for param in sig.parameters.values():
if param.name in frame.f_locals:
args.append(f"{param.name}={str(frame.f_locals[param.name])}")
cmd = f"{frame.f_code.co_name}({','.join(args)})"

print(cmd)

我得到:

>>> myfunc('a', 'b', 1, mykwarg='hello')
myfunc(a=a,b=b,c=1,mykwarg=hello)

这不完全是用户输入的内容。另外,我希望有更多的东西健壮且不那么“老套”的尝试...

用例:我希望能够将来 self 的库的命令调用与其结果相关联。我不想为每个函数硬编码命令调用存储,我更愿意使用装饰器或类似的东西。这可能在 REPL 中更容易做到,但我不想依赖它(比如,如果用户从自己的程序调用该函数,它仍然应该能够将命令调用与结果相关联)。

最佳答案

最后我回答了我自己的问题,希望有一天它能对其他人有所帮助。

我决定尝试采用 dis 方式,即。 “反汇编”的Python代码对象调用我的函数的外部框架,看看它是如何被调用的重构命令行:

import dis
import inspect
import io
import ast
import re

def get_function_call_string():
in_func = False
args=[]
kwargs=[]
func_name = inspect.stack()[1][3]
frame = inspect.currentframe().f_back.f_back
dis_output = io.StringIO()
dis.dis(frame.f_code, file=dis_output)
for line in dis_output.getvalue().split('\n'):
instr = re.findall(r'^.*\s([A-Z_]+)\s*', line)[0]
if instr.startswith("CALL_FUNCTION") and in_func:
break
elif instr.startswith('LOAD_'):
name = re.findall(r'^.*\s\((.+)\)$', line)[0]
if in_func:
if name.startswith('('):
kwargs = ast.literal_eval(name)
else:
args.append(name)
elif name == func_name:
in_func = True
kwargs = [f"{a}={args.pop()}" for a in kwargs]
return f"{func_name}({', '.join(args)}{', ' if kwargs else ''}{', '.join(kwargs)})"

例子:

>>> def f(a,b,arg="toto"):
print(get_function_call_string())
>>> f(1,"test","example")
f(1, 'test', 'example')
>>> f(1, "test", arg="hello")
(1, 'test', arg='hello')

这不是一个完整的答案,因为它无法处理某些参数类型,例如dict 或 list...我可能会继续这样做,或者改变主意,做不同的事情。

关于python - 获取 Python 函数的调用字符串,如在命令行中键入的那样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56003055/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com