"提高"其次是条件语句(python)

时间:2014-10-13 09:17:51

标签: python conditional-statements python-2.5 raise

我试图理解一些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__函数中起作用而在我的测试代码中不起作用?

2 个答案:

答案 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)