Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何从dis中获取函数参数_Python - Fatal编程技术网

Python 如何从dis中获取函数参数

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模块所期望的普通对象。 我想知道如何按顺序

如何从代码对象获取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)]

如果你有一个代码对象

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]