1

我正在使用 python 3 在我的命令行界面上运行代码。但是,我很困惑为什么dis.distb()不给我一个汇编语言代码来print("Hello World)解决缺少引号的错误。

C:\Users\jarvis>python
Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 22:20:52) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import dis
>>> print("Hello World)
  File "<stdin>", line 1
    print("Hello World)
                  ^
SyntaxError: EOL while scanning string literal
>>> dis.distb()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\jarvis\AppData\Local\Programs\Python\Python37-32\lib\dis.py", line 86, in distb
    while tb.tb_next: tb = tb.tb_next
AttributeError: 'NoneType' object has no attribute 'tb_next'

此代码为我提供了缺少字母“t”的打印功能的汇编代码

>>> prin("Hello World")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'prin' is not defined
>>> dis.distb()
  1 -->       0 LOAD_NAME                0 (prin)
              2 LOAD_CONST               0 ('Hello World')
              4 CALL_FUNCTION            1
              6 PRINT_EXPR
              8 LOAD_CONST               1 (None)
             10 RETURN_VALUE

 >>>

上面的错误类型有什么区别?我试图了解 python 在这种情况下是如何工作的。

4

2 回答 2

0

原因可能是调用 Python 解释器堆栈中的值或类型,或者可能是内存管理。另一方面,它表明dis.py无法处理SyntaxError此处发生的异常(EOL while scanning string literal)。深入研究可以追溯到sys.last_traceback前面的异常,如果它发生在交互式环境中,以进行一些事后调试。该方法的参数之一distb()是变量tb,但该参数的默认值为None。另一方面,当tbis时None,该方法将引发AttributeError。所以,这个过程表明,在你的问题的情况下,在CMDorterminal中,tb将是None,而不是在jupyter notebook.

例如,如果您在 中执行相同的操作,则jupyter notebookdis.distb()这两种情况下都可以正常工作。命令提示符下的机器人不是。

我跑了这两个案例,jupyter notebook我得到了以下结果。

print("Hello World)

# result:
  File "C:\Users\itpro\AppData\Local\Temp/ipykernel_21836/2771583741.py", line 1
    print("Hello World)
                       ^
SyntaxError: EOL while scanning string literal
# ---

dis.distb()

# result:
101           0 LOAD_GLOBAL              0 (compile)
              2 LOAD_FAST                1 (source)
              4 LOAD_FAST                2 (filename)
              6 LOAD_FAST                3 (symbol)
              8 LOAD_FAST                0 (self)
             10 LOAD_ATTR                1 (flags)
             12 LOAD_GLOBAL              2 (PyCF_ONLY_AST)
             14 BINARY_OR
             16 LOAD_CONST               1 (1)
    -->      18 CALL_FUNCTION            5
             20 RETURN_VALUE

对于第二种情况:

prin("Hello World")

# result:
NameError                                 Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_21836/2802362923.py in <module>
----> 1 prin("Hello World")

NameError: name 'prin' is not defined

# ---

dis.distb()

# result:

  1 -->       0 LOAD_NAME                0 (prin)
              2 LOAD_CONST               0 ('Hello World')
              4 CALL_FUNCTION            1
              6 PRINT_EXPR
              8 LOAD_CONST               1 (None)
             10 RETURN_VALUE
于 2021-11-03T16:57:00.980 回答
0

你没有得到字节码的反汇编的原因仅仅是因为没有:Python解释器在它可以创建任何字节码之前遇到了一个严重的错误。

这是一个非常常见的类比,但它是可用的。假设我要翻译:

“这是谁的树林,我想我知道”

成西班牙语。基本上你会理解这些单词(或者如果有人说这些单词,你可能会在你的脑海中将声音分解成音素并找出单词)。

然后你将单词拼凑成一个句子,然后你可以将句子解析成一个主语短语和宾语短语。)有了所有这些,你就可以进行翻译了。如果您听不到或不理解一个词,您可能能够弄清楚它的意思,但这是额外的工作,您可能会猜出错误的词或意思。

现在,如果我让你翻译:

“fafdsasdSFEFafef094qt43qtu08rpiekjsfdrshgoirtfhejtr4qr5841u0toiqjhwekfnsajf”

那里没有可描述的词构成一个合理的句子并且你可以解析。你能做的最好的事情就是吐出同样的东西,例如,谷歌翻译所做的。

对于现实世界的生产编译器或解释器,这些程序非常严格。(在过去,有针对会出错的初学者的语言的特殊编译器,编译器可能会尝试填写细节)。

但是在 CPython 中,如果缺少一个双引号,就像您的情况一样,CPython 会向您提供有关无效语法的消息,并带有问题所在以及可能采取的措施的指针。但它不会尝试进一步创建字节码。与谷歌翻译不同的是,它不是试图找出你可能在给出部分信息的情况下的意思。

于 2020-05-19T08:09:43.310 回答