如何动态加载和卸载Python模块、反汇编和检查它,但不执行init代码或将其添加到sys.modules?

如何动态加载和卸载Python模块、反汇编和检查它,但不执行init代码或将其添加到sys.modules?,python,inspect,Python,Inspect,我正在尝试将Python模块分解成字节码 为了反汇编或检查Python模块,我必须静态或动态地导入它吗?如果没有,有什么(pythonic,便携)方法可以做到这一点 我想: 在运行时将可用Python模块的二进制数据加载到内存中: 在sys.modules中不显示为可用模块 我不想执行任何模块的\uuuuu init\uuuu代码,也不想将其添加到任何名称空间 加载模块时不应有其他副作用。至于 对译员来说,它应该只是一个待检查的数据块 拆解或以其他方式检查模块的类别、功能或数据 需要时卸载模块

我正在尝试将Python模块分解成字节码

为了反汇编或检查Python模块,我必须静态或动态地导入它吗?如果没有,有什么(pythonic,便携)方法可以做到这一点

我想:

  • 在运行时将可用Python模块的二进制数据加载到内存中:
  • sys.modules
    中不显示为可用模块
  • 我不想执行任何模块的
    \uuuuu init\uuuu
    代码,也不想将其添加到任何名称空间
  • 加载模块时不应有其他副作用。至于 对译员来说,它应该只是一个待检查的数据块
  • 拆解或以其他方式检查模块的类别、功能或数据
  • 需要时卸载模块
  • 我已经搜索过了,我看到了许多动态模块导入的方法(它的副作用是执行module
    \uuuu init\uuuu
    代码或其他内联代码,并插入sys.modules)。但我不想处理这些副作用


    这可能吗?如果是这样的话,什么方法是最具可移植性/Pythonic的?

    我对此进行了一些研究,一个可能的解决方案是使用模块。对它的检查着眼于类和函数的基本信息,将其加载到字典中以便于访问。以下是一个运行示例:

    >>> import pyclbr
    >>> import sys
    >>> info = pyclbr.readmodule_ex('inspect')
    >>> info
    {'formatargvalues': <pyclbr.Function object at 0x5083e28e50>, 'walktree': <pyclbr.Function object at 0x5083e28b50>, 'getinnerframes': <pyclbr.Function object at 0x5083e29050>, 'indentsize': <pyclbr.Function object at 0x5083e28710>, 'getmodulename': <pyclbr.Function object at 0x5083e28850>, 'formatannotation': <pyclbr.Function object at 0x5083e28d50>, 'ismemberdescriptor': <pyclbr.Function object at 0x5083e283d0>, 'iscode': <pyclbr.Function object at 0x5083e28550>, 'getsource': <pyclbr.Function object at 0x5083e28b10>, 'formatargspec': <pyclbr.Function object at 0x5083e28dd0>, 'getabsfile': <pyclbr.Function object at 0x5083e288d0>, 'getsourcelines': <pyclbr.Function object at 0x5083e28ad0>, '_getfullargs': <pyclbr.Function object at 0x5083e28c10>, 'isabstract': <pyclbr.Function object at 0x5083e28610>, 'isbuiltin': <pyclbr.Function object at 0x5083e28590>, 'getlineno': <pyclbr.Function object at 0x5083e28f10>, 'getcomments': <pyclbr.Function object at 0x5083e28990>, 'getgeneratorstate': <pyclbr.Function object at 0x5083e293d0>, 'getattr_static': <pyclbr.Function object at 0x5083e29390>, 'getframeinfo': <pyclbr.Function object at 0x5083e28ed0>, 'isgenerator': <pyclbr.Function object at 0x5083e28490>, '_static_getmro': <pyclbr.Function object at 0x5083e29190>, 'isframe': <pyclbr.Function object at 0x5083e28510>, 'getouterframes': <pyclbr.Function object at 0x5083e28f90>, 'getclasstree': <pyclbr.Function object at 0x5083e28b90>, 'getfile': <pyclbr.Function object at 0x5083e287d0>, '_shadowed_dict': <pyclbr.Function object at 0x5083e29310>, 'getargvalues': <pyclbr.Function object at 0x5083e28d10>, 'getmembers': <pyclbr.Function object at 0x5083e28650>, 'BlockFinder': <pyclbr.Class object at 0x5083e28a10>, 'isfunction': <pyclbr.Function object at 0x5083e28390>, 'getargspec': <pyclbr.Function object at 0x5083e28c50>, 'currentframe': <pyclbr.Function object at 0x5083e29090>, 'namedtuple': <pyclbr.Function object at 0x5083e1b150>, 'getmoduleinfo': <pyclbr.Function object at 0x5083e28810>, 'trace': <pyclbr.Function object at 0x5083e29110>, 'isclass': <pyclbr.Function object at 0x5083db8950>, '_is_type': <pyclbr.Function object at 0x5083e29290>, 'getcallargs': <pyclbr.Function object at 0x5083e28e90>, 'ismethoddescriptor': <pyclbr.Function object at 0x5083e28310>, 'isgeneratorfunction': <pyclbr.Function object at 0x5083e28450>, 'isroutine': <pyclbr.Function object at 0x5083e285d0>, 'getfullargspec': <pyclbr.Function object at 0x5083e28cd0>, 'getmro': <pyclbr.Function object at 0x5083e286d0>, 'getargs': <pyclbr.Function object at 0x5083e28bd0>, 'stack': <pyclbr.Function object at 0x5083e290d0>, 'getdoc': <pyclbr.Function object at 0x5083e28750>, 'findsource': <pyclbr.Function object at 0x5083e28950>, 'cleandoc': <pyclbr.Function object at 0x5083e28790>, '_check_class': <pyclbr.Function object at 0x5083e29250>, '_check_instance': <pyclbr.Function object at 0x5083e29210>, 'classify_class_attrs': <pyclbr.Function object at 0x5083e28690>, 'ismodule': <pyclbr.Function object at 0x5083db8910>, 'EndOfBlock': <pyclbr.Class object at 0x5083e289d0>, 'isdatadescriptor': <pyclbr.Function object at 0x5083e28350>, 'getmodule': <pyclbr.Function object at 0x5083e28910>, 'formatannotationrelativeto': <pyclbr.Function object at 0x5083e28d90>, 'getsourcefile': <pyclbr.Function object at 0x5083e28890>, 'ismethod': <pyclbr.Function object at 0x5083e282d0>, 'isgetsetdescriptor': <pyclbr.Function object at 0x5083e28410>, 'istraceback': <pyclbr.Function object at 0x5083e284d0>, 'getblock': <pyclbr.Function object at 0x5083e28a50>}
    >>> sys.modules['inspect']
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    KeyError: 'inspect'
    
    导入pyclbr >>>导入系统 >>>info=pyclbr.readmodule\u ex('inspect') >>>信息 {'formatargvalues':,'walktree':,'getinnerframes':,'indentsize':,'getmodulename':,'formatannotation':,'ismemberdescriptor':,'iscode':,'getsource':,'getabsfile','getsourcelines':,'getfullargs','isabstract','isbuiltin','getlineno','getcomments','getgeneratorstate','getattr','getfr'ameinfo':,'isgenerator':,'isframe':,'getouterframes':,'getclasstree':,'getfile':,'U shadowed_dict':,'getargvalues':,'getmembers':,'BlockFinder':,'isfunction','getargspec','currentframe','NamedTupe','getmoduleinfo','trace','isclass','GetArgU是'type','getcallargs','IsMethodor','isgeneratorfunction':,'isroutine':,'getfullargspec':,'getmro':,'getargs':,'stack':,'getdoc':,'findsource':,'cleandoc':,'uCheck_class':,'uCheck_instance':,'classify_class_attrs','ismodule','EndOfBlock':,'isdatadescriptor','getmodule','formatannotationrelativeto','getsourcefile','ismethod','IsGetDescription'ptor':,'istraceback':,'getblock':} >>>系统模块['inspect'] 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 KeyError:“检查”
    任何更高级的东西,您都必须开始研究通过访问抽象语法树。

    我对此进行了研究,一个可能的解决方案是使用模块。对它的检查着眼于类和函数的基本信息,将其加载到字典中以便于访问。以下是一个运行示例:

    >>> import pyclbr
    >>> import sys
    >>> info = pyclbr.readmodule_ex('inspect')
    >>> info
    {'formatargvalues': <pyclbr.Function object at 0x5083e28e50>, 'walktree': <pyclbr.Function object at 0x5083e28b50>, 'getinnerframes': <pyclbr.Function object at 0x5083e29050>, 'indentsize': <pyclbr.Function object at 0x5083e28710>, 'getmodulename': <pyclbr.Function object at 0x5083e28850>, 'formatannotation': <pyclbr.Function object at 0x5083e28d50>, 'ismemberdescriptor': <pyclbr.Function object at 0x5083e283d0>, 'iscode': <pyclbr.Function object at 0x5083e28550>, 'getsource': <pyclbr.Function object at 0x5083e28b10>, 'formatargspec': <pyclbr.Function object at 0x5083e28dd0>, 'getabsfile': <pyclbr.Function object at 0x5083e288d0>, 'getsourcelines': <pyclbr.Function object at 0x5083e28ad0>, '_getfullargs': <pyclbr.Function object at 0x5083e28c10>, 'isabstract': <pyclbr.Function object at 0x5083e28610>, 'isbuiltin': <pyclbr.Function object at 0x5083e28590>, 'getlineno': <pyclbr.Function object at 0x5083e28f10>, 'getcomments': <pyclbr.Function object at 0x5083e28990>, 'getgeneratorstate': <pyclbr.Function object at 0x5083e293d0>, 'getattr_static': <pyclbr.Function object at 0x5083e29390>, 'getframeinfo': <pyclbr.Function object at 0x5083e28ed0>, 'isgenerator': <pyclbr.Function object at 0x5083e28490>, '_static_getmro': <pyclbr.Function object at 0x5083e29190>, 'isframe': <pyclbr.Function object at 0x5083e28510>, 'getouterframes': <pyclbr.Function object at 0x5083e28f90>, 'getclasstree': <pyclbr.Function object at 0x5083e28b90>, 'getfile': <pyclbr.Function object at 0x5083e287d0>, '_shadowed_dict': <pyclbr.Function object at 0x5083e29310>, 'getargvalues': <pyclbr.Function object at 0x5083e28d10>, 'getmembers': <pyclbr.Function object at 0x5083e28650>, 'BlockFinder': <pyclbr.Class object at 0x5083e28a10>, 'isfunction': <pyclbr.Function object at 0x5083e28390>, 'getargspec': <pyclbr.Function object at 0x5083e28c50>, 'currentframe': <pyclbr.Function object at 0x5083e29090>, 'namedtuple': <pyclbr.Function object at 0x5083e1b150>, 'getmoduleinfo': <pyclbr.Function object at 0x5083e28810>, 'trace': <pyclbr.Function object at 0x5083e29110>, 'isclass': <pyclbr.Function object at 0x5083db8950>, '_is_type': <pyclbr.Function object at 0x5083e29290>, 'getcallargs': <pyclbr.Function object at 0x5083e28e90>, 'ismethoddescriptor': <pyclbr.Function object at 0x5083e28310>, 'isgeneratorfunction': <pyclbr.Function object at 0x5083e28450>, 'isroutine': <pyclbr.Function object at 0x5083e285d0>, 'getfullargspec': <pyclbr.Function object at 0x5083e28cd0>, 'getmro': <pyclbr.Function object at 0x5083e286d0>, 'getargs': <pyclbr.Function object at 0x5083e28bd0>, 'stack': <pyclbr.Function object at 0x5083e290d0>, 'getdoc': <pyclbr.Function object at 0x5083e28750>, 'findsource': <pyclbr.Function object at 0x5083e28950>, 'cleandoc': <pyclbr.Function object at 0x5083e28790>, '_check_class': <pyclbr.Function object at 0x5083e29250>, '_check_instance': <pyclbr.Function object at 0x5083e29210>, 'classify_class_attrs': <pyclbr.Function object at 0x5083e28690>, 'ismodule': <pyclbr.Function object at 0x5083db8910>, 'EndOfBlock': <pyclbr.Class object at 0x5083e289d0>, 'isdatadescriptor': <pyclbr.Function object at 0x5083e28350>, 'getmodule': <pyclbr.Function object at 0x5083e28910>, 'formatannotationrelativeto': <pyclbr.Function object at 0x5083e28d90>, 'getsourcefile': <pyclbr.Function object at 0x5083e28890>, 'ismethod': <pyclbr.Function object at 0x5083e282d0>, 'isgetsetdescriptor': <pyclbr.Function object at 0x5083e28410>, 'istraceback': <pyclbr.Function object at 0x5083e284d0>, 'getblock': <pyclbr.Function object at 0x5083e28a50>}
    >>> sys.modules['inspect']
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    KeyError: 'inspect'
    
    导入pyclbr >>>导入系统 >>>info=pyclbr.readmodule\u ex('inspect') >>>信息 {'formatargvalues':,'walktree':,'getinnerframes':,'indentsize':,'getmodulename':,'formatannotation':,'ismemberdescriptor':,'iscode':,'getsource':,'getabsfile','getsourcelines':,'getfullargs','isabstract','isbuiltin','getlineno','getcomments','getgeneratorstate','getattr','getfr'ameinfo':,'isgenerator':,'isframe':,'getouterframes':,'getclasstree':,'getfile':,'U shadowed_dict':,'getargvalues':,'getmembers':,'BlockFinder':,'isfunction','getargspec','currentframe','NamedTupe','getmoduleinfo','trace','isclass','GetArgU是'type','getcallargs','IsMethodor','isgeneratorfunction':,'isroutine':,'getfullargspec':,'getmro':,'getargs':,'stack':,'getdoc':,'findsource':,'cleandoc':,'uCheck_class':,'uCheck_instance':,'classify_class_attrs','ismodule','EndOfBlock':,'isdatadescriptor','getmodule','formatannotationrelativeto','getsourcefile','ismethod','IsGetDescription'ptor':,'istraceback':,'getblock':} >>>系统模块['inspect'] 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 KeyError:“检查” 任何更高级的东西,您都必须开始通过我为Python2.7找到的。

    来访问抽象语法树,它包含到模块的函数和不导入模块的函数

    因此,至少它看起来是可行的,但可能涉及在源代码上调用
    compile()
    ,或者,如果使用pyc文件,可能不可移植(Unmyle2仅支持pyc文件的Python 2.7)。

    我为Python 2.7找到了它,它包含到模块和不导入模块的函数


    因此,至少它看起来是可行的,但可能涉及在源代码上调用
    compile()
    ,或者,如果使用pyc文件,可能不可移植(Unmyle2仅支持pyc文件的Python 2.7)。

    在不允许执行init.py文件的情况下“加载模块”意味着什么?在我看来,这似乎是一个矛盾。将二进制数据以代码可以访问但不能执行的形式加载到内存中。我已经更新了这个问题以反映您的反馈,“加载模块”而不允许它执行init.py文件意味着什么?在我看来,这似乎是一个矛盾。将二进制数据以代码可以访问但不能执行的形式加载到内存中。我已经更新了这个问题,以反映您的反馈,这很有帮助,因为我确实需要类浏览器功能,但公开的接口不能帮助我满足核心需求。我将深入到pyclbr代码中,看看该实现是否提供了额外的线索,因此+1是您的答案@不作为主义者,你能在re上再扩展一点吗