为什么Python编译器在exit()之后不忽略语法错误?

Ali*_*aby 0 python compilation compiler-optimization

如果运行Python代码然后调用exit(),它将退出程序并且以下代码将不会运行。但是我添加exit()到我的程序中,然后出现一些语法错误并且程序崩溃了。我想知道为什么 Python 编译器在运行之前没有优化我的代码。我用逻辑错误尝试了这个问题,但它忽略了它们,比如index out of range等等。那么为什么下面的代码不起作用并SyntaxError发生呢?

print("Hi")
exit()
if 
Run Code Online (Sandbox Code Playgroud)

Pet*_*des 5

它无法准确地编译您的程序,因为它是一个编译器(编译为稍后将解释的字节码)。当它看到 时,它不会停止解析exit(),这与 shell 一次一行读取和解释 shell 脚本不同。(顺便说一句,这不是“优化”)。

Python 将其编译为字节码,exit如果到达程序中的该点,则调用该字节码。即使无法访问的代码也必须在语法上有效,以便整个文件能够编译。但由于它从未实际执行,因此不会导致任何运行时错误。

这不是一个任意的过程。C 编译器工作得更聪明 C 编译器如何检测它?

例如,如果您while 1用 C 运行一个程序,它由于逻辑原因而无法运行。但为什么 python 不做同样的事情呢?

这不是真的。

C 编译器会因无法访问的块中的语法错误而窒息,例如int foo(){ if(0) if if; }. 另外,while 1这不是有效的 C 语法。

https://godbolt.org/z/cP83Y866b。只有#if 0 预处理器的内容或注释可以向编译器隐藏内容,因此它不必是有效的语法和语法。

语法和文法需要在整个文件中有效,才能解析为编译器可以编译的内容。

在 C 和 C++ 中,无法访问的代码(未注释掉)甚至必须在类型匹配方面有效,例如,如果is但其类型是,则T x = y;不会编译。这在语法上是有效的,但“格式错误”。Per cppreference在模板之外,会完全检查已丢弃的语句。不能替代预处理指令Tintychar*if constexpr#if

但在模板内部,它可以隐藏一些东西。 https://godbolt.org/z/frTcbMb3T

template <typename T>  // being a template function makes if constexpr special
void foo(int x) {
  if constexpr (false) {
      int x = "hi";    // ill-formed, type mismatch.  But still valid *syntax*
  }

#if 1           // 0 would truly ignore all text until the closing #endif
  if constexpr (false) {
//      int x = = 2;  // syntax error if uncommented
  }
#endif
}
Run Code Online (Sandbox Code Playgroud)