我试图理解一些python 2.5代码,我遇到了这种模式:
def __init__(self, matrix, top_buttons, side_buttons, config_button):
raise isinstance(matrix, ButtonMatrixElement) or AssertionError
raise matrix.width() == 8 and matrix.height() == 8 or AssertionError
raise isinstance(top_buttons, tuple) or AssertionError
raise len(top_buttons) == 8 or AssertionError
raise isinstance(side_buttons, tuple) or AssertionError
raise len(side_buttons) == 8 or AssertionError
raise isinstance(config_button, ButtonElement) or AssertionError
我尝试在shell中使用一些简单的条件语句对此进行测试:
>>> str = 'hello'
>>> raise len(str) == 5 or AssertionError
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
raise len(str) == 5 or AssertionError
TypeError: exceptions must be classes, instances, or strings (deprecated), not bool
所以从这个测试判断,至少我尝试它的方式,你不能提出一个布尔语句。那么提出一个条件表达式是什么意思,为什么它在__init__
函数中起作用而在我的测试代码中不起作用?
答案 0 :(得分:8)
代码是无稽之谈,对于看起来像assert
statement的东西的拙劣尝试,如你所发现的那样失败了。
应撰写的内容是:
assert isinstance(matrix, ButtonMatrixElement)
等等。
您似乎找到了decompiled Ableton Live scripts,但反编译脚本产生了错误的Python代码。 assert
的字节码如下所示(Python 2.5字节码):
>>> import dis
>>> dis.dis(compile('''assert isinstance(matrix, ButtonMatrixElement)''', '<stdin>', 'exec'))
1 0 LOAD_NAME 0 (isinstance)
3 LOAD_NAME 1 (matrix)
6 LOAD_NAME 2 (ButtonMatrixElement)
9 CALL_FUNCTION 2
12 JUMP_IF_TRUE 7 (to 22)
15 POP_TOP
16 LOAD_GLOBAL 3 (AssertionError)
19 RAISE_VARARGS 1
>> 22 POP_TOP
23 LOAD_CONST 0 (None)
26 RETURN_VALUE
看起来好像使用了任何自动化过程来将转换后的字节码反编译为您看到的代码而不是将其识别为assert
。
但请注意,如果isinstance()
调用返回True
,则跳转指令(索引12,JUMP_IF_TRUE
)跳过过去 RAISE_VARARGS
指令虽然重构的代码没有。将其与实际的raise ... or ...
语句进行比较,您会注意到跳转不会超过raise
:
>>> dis.dis(compile('raise foo or bar', '<stdin>', 'exec'))
1 0 LOAD_NAME 0 (foo)
3 JUMP_IF_TRUE 4 (to 10)
6 POP_TOP
7 LOAD_NAME 1 (bar)
>> 10 RAISE_VARARGS 1
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
据推测,代码生成器处理这个问题并不复杂;如果您仅假设or
生成JUMP_IF_TRUE
并且未正确处理偏移,则可以看到错误是如何产生的。
答案 1 :(得分:2)
如前所述,这是反编译器中的一个错误,它在python字节代码的逆向工程过程中使用过。如果您想自己反编译文件,可以使用以下版本的脚本:
https://github.com/frankebersoll/uncompyle2
应该在那里修复上述错误。使用此版本反编译MainSelectorComponent.pyc
时,您会得到:
class MainSelectorComponent(ModeSelectorComponent):
""" Class that reassigns the button on the launchpad to different functions """
def __init__(self, matrix, top_buttons, side_buttons, config_button):
assert isinstance(matrix, ButtonMatrixElement)
assert matrix.width() == 8 and matrix.height() == 8
assert isinstance(top_buttons, tuple)
assert len(top_buttons) == 8
assert isinstance(side_buttons, tuple)
assert len(side_buttons) == 8
assert isinstance(config_button, ButtonElement)