交互式控制台中,Python 用什么算法来决定使用 >>> 还是 ... 提示符?

3
我正在实现一个自定义的(Iron)Python控制台。
通常情况下,我需要显示一个>>>提示符,但是当语句不完整时,我需要将提示符更改为...并收集更多行以便执行它们。
我如何知道用户输入的一行是否完整或者我需要读取更多行?
一个简单的方法似乎是检查是否存在:。但是我不确定是否漏掉了其他:不存在的情况。
我查看了IronPython源代码来弄清楚它是如何做到这一点的,但涉及到许多步骤,我的简单复制未能完全工作。
4个回答

5
仅仅通过查看代码字符串来猜测冒号和括号是不切实际的。你最终需要实现一半的Python解析器才能做到这一点。标准库code模块复制了交互式Python解释器的行为,我认为这个模块是IronPython用于实现其控制台的模块。(CPython没有在Python本身中实现。) 你感兴趣的行连续逻辑来自codeop.compile_command函数。这有点像黑客行为。它基本上尝试使用晦涩的PyCF_DONT_IMPLY_DEDENT标志编译给定的代码,这意味着它不会假设任何打开缩进都会在块结束时自动关闭。然后它尝试添加换行符(导致显式的DEDENT),再次进行编译。如果第二个工作但第一个不工作,你就有了潜在的连续性,可以在块中输入更多内容。

有些黑客式的,但在实际应用中看到过,所以加一分。 - SingleNegationElimination

3

我能想到几种方法来获得...提示。

  • 开始(或继续)一个块
    • def foo():
  • 未关闭的括号、大括号、方括号(注意嵌套)
    • x = (
    • x = {
    • x = [
  • 未关闭的三引号字符串
    • x = '''
  • 行末反斜杠:
    • x = \

3

repl循环具有对解析器的完全知识和访问权限。 如果解析器状态不是期望语句之外的任何内容,则repl循环会生成...。 在未关闭的括号情况下,下一行将无法使用语句,因为没有可能包含语句的子表达式。 在:之后,下一个预期的标记始终是缩进,再次,语句总是非法的。 这就是为什么在repl循环中必须始终在缩进块的末尾键入空行,因为您必须提供关闭dedent以使语句成为下一个预期的产生规则。


1

你使用了 : 还是 \(或者未关闭的分隔符,比如括号或圆括号)?交互式解释器会显示一个 ...

实际逻辑可能会更加复杂,但这是基本规则。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接