首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对代码对象使用uncompyle6的正确方法是什么?

对代码对象使用uncompyle6的正确方法是什么?
EN

Stack Overflow用户
提问于 2018-07-12 18:28:20
回答 1查看 3.3K关注 0票数 3

我在github (原件)上找到了这个例子,但这似乎非常过时,所以我对它做了一些修改。

代码语言:javascript
复制
from uncompyle6.main import decompile 
import sys

def uncompyle_test():
    gen = (expr1 if cond1 else expr2 for A in [] if (expr3 if cond2 else expr4))
    co = gen.gi_code
    decompile (3.6, co, sys.stdout, showast=False)

uncompyle_test()

通过运行这个程序,我可以得到.0A if expr3 if cond2 else expr4。这似乎是不正确的。我是漏掉了什么还是只是个虫子?

EN

回答 1

Stack Overflow用户

发布于 2018-09-18 20:44:21

这不是一个完整的答案,但它应该能让你对发生的事情有一些了解。

首先要注意的是,传递给decompile()函数的字节码版本应该与您正在运行的Python相同,因为这是正在生成的字节码。xdis有一个功能来确保:

代码语言:javascript
复制
>>> from xdis.magics import sysinfo2float
>>> sysinfo2float()
3.6

不过,我会假设情况就是这样。

其次,当您对整个程序进行反编译时,您得到了一个正确的结果:

代码语言:javascript
复制
# uncompyle6 version 3.2.3
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.5 (default, Apr  9 2018, 01:37:56) 
# [GCC 7.2.0]
# Embedded file name: exec
# Compiled at: 2018-09-18 16:10:11
# Size of source mod 2**32: 243 bytes
from uncompyle6.main import decompile
import sys

def uncompyle_test():
    gen = ((expr1 if cond1 else expr2) for A in [] if (expr3 if cond2 else expr4))
    co = gen.gi_code
    decompile(3.6, co, sys.stdout, showast=False)

那为什么你的尝试不起作用呢?主要的问题是,uncompyle6需要知道它想要的是什么类型的东西。回想一下,compile()函数有三种“模式”:"exec“、"eval”和"single“。

来自compile()的Python

模式参数指定必须编译哪种代码;如果源由一系列语句组成,则可以是“exec”;如果它由单个表达式组成,则为“eval”;如果它由单个交互式语句组成,则为“单项”。

在这里,上下文是一个生成器,它是一种表达式。uses ()不允许您选择您指的是哪个,而使用"exec“。在较低的解析级别上,虽然您区分了"exec“和"single",但是目前还没有一种方法来指定"eval”,更不用说在这个特定的函数中了。我已经打开了一个uncompyle6问题来注意这一点。

最后,让我们更详细地描述一下为什么你看到的是你所看到的。

为此,让我们使用我编写的这个方便而独特的调试器,它向您展示了在离开过程中发生了什么,但更重要的是在这里进行了反汇编。

代码语言:javascript
复制
$ trepan3k /tmp/bug.py 
(/tmp/bug.py:1): <module>
-> 1 from uncompyle6.main import decompile
Rocky's Python Trepan Python code startup loaded
(trepan3k) next 2
(/tmp/bug.py:9 @28): <module>
-- 9 uncompyle_test()
(trepan3k) step
(/tmp/bug.py:4): uncompyle_test
-> 4 def uncompyle_test():
(trepan3k) next 3
(/tmp/bug.py:7 @20): uncompyle_test
-- 7     decompile (3.6, co, sys.stdout, showast=False)
(trepan3k) disasm co
Disassembly of <code object <genexpr> at 0x7f6a3faff300, file "/tmp/bug.py", line 5>: 
   5        0 LOAD_FAST           0          .0                  
       >>   2 FOR_ITER            30         to 34               
            4 STORE_FAST          1          A                   
            6 LOAD_GLOBAL         0          cond2               
            8 POP_JUMP_IF_FALSE   14         to 14               
           10 LOAD_GLOBAL         1          expr3               
           12 JUMP_FORWARD        2          to 16               
       >>  14 LOAD_GLOBAL         2          expr4               
       >>  16 POP_JUMP_IF_FALSE   2          to 2                
           18 LOAD_GLOBAL         3          cond1               
           20 POP_JUMP_IF_FALSE   26         to 26               
           22 LOAD_GLOBAL         4          expr1               
           24 JUMP_FORWARD        2          to 28               
       >>  26 LOAD_GLOBAL         5          expr2               
       >>  28 YIELD_VALUE         None                           
           30 POP_TOP             None                           
           32 JUMP_ABSOLUTE       2          to 2                
       >>  34 LOAD_CONST          0          None                
           36 RETURN_VALUE        None                           
(trepan3k) Leaving
trepan3k: That's all, folks...

因此,您可以看到,.0确实来自于代码:它是生成器内部使用的一个临时变量。然而,应该有某种“for”,而"in []“也不见了。这是缺失的,因为其他地方的代码设置了这个部分,我想。

总之,事情有点怪怪的,因为高层环境不对。假设这是单个表达式的语法规则应该用于完整的程序,而不是语法规则。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51312282

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档