我所知道的许多语言(例如C ++,C,Rust等)一次打印多个错误消息。那么为什么python只打印一条错误消息?
答案 0 :(得分:3)
首先,我假设我们正在谈论语法错误,即编译器可以(并且应该)检测和报告的语法错误。
这主要是设计选择。 Python基本上是建立在运行时应完成所有操作的概念上的。并且故意使编译器保持尽可能简单。
简单易懂,或者复杂复杂: 简而言之,您可以选择使用易于理解和维护的非常简单的编译器,或者使用复杂的程序进行复杂的程序分析和优化。
诸如C,C ++和Rust之类的语言在编译过程中充分利用了代码的高度优化,因此在高度复杂和极其复杂的编译器中走了第二条路。处理语法错误是他们不那么令人印象深刻的壮举之一。
另一方面,Python使用了其他方法。实际上,总的来说,对于Python编译器来说,如果不实际运行它,就不可能预测一段Python代码的精确性,这一开始就排除了所有有趣的优化机会,因此,复杂的编译器实际上并不会不管怎么说因此,使Python的编译器保持简单,而专注于运行时优化是正确的选择。但是它有一个缺点,那就是编译器在发现错误时就会自动退出。
提供更多背景信息...
很难在编译器中处理错误并从语法错误中恢复。
编译器通常善于快速有效地将(正确的)正确程序翻译为代表原始程序的机器代码。但是,如果出现语法错误,则编译器通常无法猜测程序员的初衷,因此,不清楚如何处理错误的代码。>
这是一个非常简单的示例:
pen color("red")
很明显,这里有问题,但是如果没有进一步的上下文,就无法确定此行的原始意图是pen = color("red")
,pencolor("red")
,pen.color("red")
还是其他所有东西
如果编译器希望继续查看程序的其余部分(从而发现潜在的更多语法错误),则需要对如何应对这种情况并进行恢复以继续进行下去有一个严格的要求:它需要一个< em>错误恢复策略。这可能只是跳过整个行或单个标记而已,但没有针对此的明确“正确”解决方案。
Python一次编译一个符号。
Python当前的编译器通过一次查看一个符号(称为LL(1)
编译器)来工作。这使得为Python自动构建编译器变得极其简单,并且非常快速和有效。但这意味着在某些情况下,尽管存在“明显的”语法错误,但Python还是乐于继续编译程序,直到它真正丢失为止。
看看这个例子:
x = foo(
y = bar()
if x > y:
作为人类,我们很快就会在第1行中看到缺少的右括号。但是,从编译器的角度来看,这看起来像是带有命名参数的调用,如下所示:
x = foo(y = bar() if x > y else 0)
因此,Python只会在第3行碰到冒号时才发现错误,这是第一个不适用于其“假设”的符号。但是到那时,要弄清楚如何处理这段代码以及如何正确恢复是非常困难的:在这种情况下,您是否只是跳过冒号?还是应该回过头去更早地进行更正?如果是,那么要走多远?
错误恢复可以创建“幽灵”错误。
在上面的第一个示例中,编译器可以跳过整行并继续前进而不会出现任何问题。但是在某些情况下,如何从语法错误中恢复的选择会(可能)影响随后的所有操作,如以下示例所示:
deffoo(x):
此操作的目的可能是def foo(x):
,也可能只是调用deffoo(x)
。但是这种区别决定了编译器如何看待随后的代码,并报告缩进错误,或者报告函数外的return
等。
错误恢复的危险在于,编译器的猜测实际上可能是错误的,这可能导致报告的一系列后续错误-甚至可能不是真正的错误,而是编译器错误决定所造成的重影。
底线:正确进行错误恢复和错误报告非常困难。因此,Python选择只报告它遇到的第一个语法错误是明智的,并且适用于大多数用户和情况。
我实际上已经写了parser with more sophisticated error detection,它可以列出它在Python程序中发现的所有错误。但是根据我的经验,除了第一个错误以外,还有很多其他错误仅仅是垃圾,因此我始终坚持只在程序中显示第一个错误。
答案 1 :(得分:0)
难以回答确切原因。我看不到C-python,jython,pypy或其他语言的开发人员的脑袋。
许多错误只会在运行时出现,因为python是一种无需严格输入的解释语言。
但是,如果没有语法错误,则将每个文件编译为字节码。
因此,对于语法错误,我无法给出原因,因为从技术上讲应该是可以的。但是,由于我使用var to = Request.Form["To"]; // your twilio number
var body = Request.Form["Body"]; // the message they sent
或pylint
之类的工具来为我检查代码,因此我对此从未遇到任何问题。
这些工具可以检测到多个错误,并且还可以提供许多有关编码样式的警告。
所以我无法告诉您原因,而只能告诉您如何一次性获得多个错误。
可以将这些工具配置为仅显示某些类型的错误。
要安装一个或另一个工具,只需键入:
flake8
或pip install flake8
然后在所有代码所在的目录中仅键入pip install pylint
或flake8
或输入pylint
或flake8 <filename>
仅检查一个文件。
请注意,可以将许多IDE(例如Microsoft Visual Studio Code,Pycharm等)配置为自动为您运行这些工具,并在执行代码之前发出任何问题的信号。
答案 2 :(得分:0)
C或C ++使用编译器进行编译,然后执行,但是python是一种解释语言,这意味着解释器读取每一行,然后在解释器看到程序行停止运行并在其他程序中显示错误时执行该命令像JS这样的解释语言是相同的。 希望您的问题得到解决,但是如果您想了解更多信息,可以在Google“解释和编译语言”中查看或查看this