如何从代码对象获取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模块中获得期望。 我想知道如何按顺序获取函数参数列表。在这种情况下,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)]
答案 0 :(得分:1)
如果您有代码对象
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',)
答案 1 :(得分:0)
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运行时基于堆栈),并且RETURN_VALUE
从函数返回,其值在堆栈顶部。这里没有提及a
或b
。这是有道理的。他们不被使用!字节字节码与函数参数无关。它将发出必要的操作,以将它们放入堆栈中(需要时):
>>> 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
并将它们压入堆栈,以BINARY_ADD
(将堆栈中的前两个值相加并压入结果)
您可以使用__code__
来获得所需的内容,特别是:
params_and_locals = f.__code__.co_varnames
num_args = f.__code__.co_argcount + f.__code__.co_kwonlyargcount
params = params_and_locals[:num_args]