我在github (原件)上找到了这个例子,但这似乎非常过时,所以我对它做了一些修改。
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。这似乎是不正确的。我是漏掉了什么还是只是个虫子?
发布于 2018-09-18 20:44:21
这不是一个完整的答案,但它应该能让你对发生的事情有一些了解。
首先要注意的是,传递给decompile()函数的字节码版本应该与您正在运行的Python相同,因为这是正在生成的字节码。xdis有一个功能来确保:
>>> from xdis.magics import sysinfo2float
>>> sysinfo2float()
3.6不过,我会假设情况就是这样。
其次,当您对整个程序进行反编译时,您得到了一个正确的结果:
# 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问题来注意这一点。
最后,让我们更详细地描述一下为什么你看到的是你所看到的。
为此,让我们使用我编写的这个方便而独特的调试器,它向您展示了在离开过程中发生了什么,但更重要的是在这里进行了反汇编。
$ 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 []“也不见了。这是缺失的,因为其他地方的代码设置了这个部分,我想。
总之,事情有点怪怪的,因为高层环境不对。假设这是单个表达式的语法规则应该用于完整的程序,而不是语法规则。
https://stackoverflow.com/questions/51312282
复制相似问题