Python IDLE使用“print”语句进行错误调用

时间:2012-05-26 08:47:12

标签: python syntax-highlighting python-idle

proof of point http://adams-site.x10.mx/v/python.png

你会注意到在这张图片中,两个印刷语句是不同的颜色。

这并不重要,我并不是真的很烦,但我认为知道原因或者这只是一个错误会很好。

(我看过this链接,但我真的很想知道为什么。)

2 个答案:

答案 0 :(得分:5)

根据您在上一个问题中提到的bug report,IDLE与TrueFalseNone混淆了很长时间不是关键字虽然,但是成为Py3.0的关键词 - 在成为关键词之前,它们只是内置全局命名空间中的名字。因此,IDLE会在不同的上下文之间将它们标记为内置函数或不一致的关键字。

print经历了完全相反的转换 - 它是一个直到3.0的关键字,之后它只是一个内置的(因为它现在是一个函数,而不是一个语句)。因此,IDLE会两种方式对其进行着色,具体取决于它如何解析它认为适用的方式。这似乎是由同一个补丁解决的(仅在3.2及以上,而不是任何2.x分支) - print始终为紫色。

答案 1 :(得分:5)

这是负责ColorDelegator.py语法高亮的代码:

def any(name, alternates):
    "Return a named group pattern matching list of alternates."
    return "(?P<%s>" % name + "|".join(alternates) + ")"

def make_pat():
    kw = r"\b" + any("KEYWORD", keyword.kwlist) + r"\b"
    builtinlist = [str(name) for name in dir(__builtin__)
                                        if not name.startswith('_')]
    # self.file = file("file") :
    # 1st 'file' colorized normal, 2nd as builtin, 3rd as string
    builtin = r"([^.'\"\\#]\b|^)" + any("BUILTIN", builtinlist) + r"\b"
    comment = any("COMMENT", [r"#[^\n]*"])
    sqstring = r"(\b[rRuU])?'[^'\\\n]*(\\.[^'\\\n]*)*'?"
    dqstring = r'(\b[rRuU])?"[^"\\\n]*(\\.[^"\\\n]*)*"?'
    sq3string = r"(\b[rRuU])?'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?"
    dq3string = r'(\b[rRuU])?"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?'
    string = any("STRING", [sq3string, dq3string, sqstring, dqstring])
    return kw + "|" + builtin + "|" + comment + "|" + string +\
           "|" + any("SYNC", [r"\n"])

它构建了一个大的正则表达式,用于将项目与颜色匹配。特别是,定义为kw的正则表达式将匹配源文件中找到的关键字(由keyword module定义),而定义为builtin的正则表达式将匹配内置函数(通过扫描__builtin__发现的,只要它不遵循句号,引号,双引号,反斜杠或哈希符号。

现在,有一些因素可以解决您看到的奇怪行为。首先,在Python 2.7 print中既是关键字又是内置函数。 (我不确定为什么,但我想可能会更接近Python 3.0,其中print显然是内置而不是关键字。)因此构造了一个正则表达式,可以将print匹配为关键字或一个内置的。但为什么它有时会匹配为一个而有时与另一个匹配?

差异是由于正则表达式的构建。在一行的开头,kw正则表达式与第一个字符匹配,并且在考虑其余字符之前匹配。但是,在行开始之后,builtin正则表达式实际上与之前的字符匹配,因为它查找的第一个字符是“任何不是句点,引号,双引号,反斜杠或哈希的字符” 。即使该字符未包含在标记组中,它仍然是匹配的一部分。因此,当print前面有空格或制表符时,builtin正则表达式首先匹配。

解决这个问题的一种方法是使用负面的lookbehind断言,但是这种复杂的正则表达式已经让我有点紧张,而且我不确定哪些正则表达式功能会导致灾难性的性能下降。一个更简单的解决方法是在构造正则表达式之前过滤掉任何也是关键字的内置函数,这正是Python 3.2.2中所做的,正如从您引用的问题链接的错误报告中所描述的那样。