python - "raise"后跟条件语句(python)

标签 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

所以从这个测试来看,至少我试过的方式,你不能引发一个 bool 语句。那么引发条件表达式是什么意思,为什么它在 __init__ 函数中起作用但在我的测试代码中不起作用?

最佳答案

代码是胡说八道,是对看起来像 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        

并且看起来好像使用任何自动过程来反编译字节码将其翻译成您看到的代码,而不是将其识别为断言

但是请注意,如果 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        

大概是代码生成器处理这个问题不够复杂;如果您假设只有 生成 JUMP_IF_TRUE 并且没有正确处理偏移量,您可以看到错误是如何产生的。

关于python - "raise"后跟条件语句(python),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26336545/

相关文章:

python celery : Update django model after state change

perl - 我应该使用 Perl 的条件吗? : operator as a switch/case statement or instead of if elsif?

pytorch - 如何解决运行时错误 "Only Tensors created explicitly by the user (graph leaves) support the deepcopy protocol at the moment"

python - 正则表达式子函数不适用于 unicode 字符串

Python Pandas read_excel 无法识别空单元格

Python:身份验证凭据异常: "Request had invalid authentication credentials. Expected OAuth 2 access token"

调用 intern() 的 Python 2 和 3 兼容方式

excel - 在特殊条件下将一系列单元格粘贴到相同大小的目标范围?

xaml - Xamarin XAML 条件样式

python - 将邻接表变成表