Python 如何从dis中获取函数参数
如何从代码对象获取python中的函数参数列表Python 如何从dis中获取函数参数,python,Python,如何从代码对象获取python中的函数参数列表 import xdis.std as dis ops = list(dis.Bytecode("""def f(a, b): return 1""")) print(ops) code_obj = ops[0] print(list(dis.Bytecode(code_obj.argval))) 上述代码使用xdis模块对需要通过pip安装的代码进行反编译。但是,代码对象是python中默认dis模块所期望的普通对象。 我想知道如何按顺序
import xdis.std as dis
ops = list(dis.Bytecode("""def f(a, b):
return 1"""))
print(ops)
code_obj = ops[0]
print(list(dis.Bytecode(code_obj.argval)))
上述代码使用xdis模块对需要通过pip安装的代码进行反编译。但是,代码对象是python中默认dis模块所期望的普通对象。
我想知道如何按顺序获得函数参数列表。在这种情况下,a和b
这是交互式python中的输出-
>>> import xdis.std as dis
>>> ops = list(dis.Bytecode("""def f(a, b):
... return 1"""))
>>> print(ops)
[Instruction(opname='LOAD_CONST', opcode=100, optype='const', inst_size=2, arg=0, argval=<code object f at 0x7a1a5c4f60, file "<disassembly>", line 1>, argrepr='<code object f at 0x7a1a5c4f60, file "<disassembly>", line 1>', has_arg=True, offset=0, starts_line=1, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, optype='const', inst_size=2, arg=1, argval='f', argrepr="'f'", has_arg=True, offset=2, starts_line=None, is_jump_target=False), Instruction(opname='MAKE_FUNCTION', opcode=132, optype=None, inst_size=2, arg=0, argval=0, argrepr='', has_arg=True, offset=4, starts_line=None, is_jump_target=False), Instruction(opname='STORE_NAME', opcode=90, optype='name', inst_size=2, arg=0, argval='f', argrepr='f', has_arg=True, offset=6, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, optype='const', inst_size=2, arg=2, argval=None, argrepr='None', has_arg=True, offset=8, starts_line=None, is_jump_target=False), Instruction(opname='RETURN_VALUE', opcode=83, optype=None, inst_size=2, arg=None, argval=None, argrepr='', has_arg=False, offset=10, starts_line=None, is_jump_target=False)]
>>> code_obj = ops[0]
>>> print(list(dis.Bytecode(code_obj.argval)))
[Instruction(opname='LOAD_CONST', opcode=100, optype='const', inst_size=2, arg=1, argval=1, argrepr='1', has_arg=True, offset=0, starts_line=2, is_jump_target=False), Instruction(opname='RETURN_VALUE', opcode=83, optype=None, inst_size=2, arg=None, argval=None, argrepr='', has_arg=False, offset=2, starts_line=None, is_jump_target=False)]
如果你有一个代码对象
def f(a, b, *, c=True):
e = a + b
if c:
return a * e
code_obj = f.__code__
然后确定位置参数
code_obj.co_varnames[:code_obj.co_argcount]
# --> ('a', 'b')
code_obj.co_varnames[code_obj.co_argcount : code_obj.co_argcount + code_obj.co_kwonlyargcount]
# --> ('c',)
并且只有关键字参数是
code_obj.co_varnames[:code_obj.co_argcount]
# --> ('a', 'b')
code_obj.co_varnames[code_obj.co_argcount : code_obj.co_argcount + code_obj.co_kwonlyargcount]
# --> ('c',)
xdis在这里不会给您提供很多有用的功能。它只是给了你更多的对象化输出,理论上你可以比普通的dis模块更容易处理。但是,股票模块告诉我们所有我们需要知道的:
>>> from dis import dis
>>> def f(a, b):
... return 1
...
>>> dis(f)
2 0 LOAD_CONST 1 (1)
2 RETURN_VALUE
请注意拆解如何仅包括两个操作码。LOAD_CONST将1推送到堆栈上cpython运行时基于堆栈,返回函数返回的_值,值位于堆栈顶部。这里没有提到a和b。这是有道理的。他们没用!字节字节代码本身与函数参数无关。它将发出必要的ops,以便在需要时将它们放在堆栈上:
>>> def f(a, b):
... return a + b
...
>>> dis(f)
2 0 LOAD_FAST 0 (a)
2 LOAD_FAST 1 (b)
4 BINARY_ADD
6 RETURN_VALUE
请注意,LOAD_FAST获取a和b并将它们推送到二进制_ADD的堆栈上,二进制_ADD将堆栈上的前两个值相加并推送结果
您可以通过使用__;代码__;获得所需,具体如下:
params_and_locals = f.__code__.co_varnames
num_args = f.__code__.co_argcount + f.__code__.co_kwonlyargcount
params = params_and_locals[:num_args]