1

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

You'll notice in this image the two print statements are different colours.

It doesn't really matter a great deal, I'm not really bothered, but I thought it would be nice to know why, or if this is just a bug.

(I have seen this link, but I really would like to know why.)

4

2 回答 2

5

根据您提到的上一个问题中链接的错误报告True,IDLE 被混淆了内置的全局命名空间。因此,IDLE 会在不同的上下文之间,将它们不一致地着色为内置函数或关键字。FalseNone

print经历了完全相反的转变——在 3.0 之前它是一个关键字,之后它只是一个内置函数(因为它现在是一个函数,而不是一个语句)。因此,IDLE 以两种方式着色,这取决于它如何解决它认为适用的一种。这似乎可以通过同一个补丁(仅在 3.2 及更高版本中,而不是任何 2.x 分支)解决 -print始终呈紫色。

于 2012-05-26T09:32:23.443 回答
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的关键字(由关键字模块builtin定义),而定义为的正则表达式将匹配内置函数(由扫描发现__builtin__)只要它不跟随句点、引号、双引号、反斜杠或井号。

现在,有多种因素在起作用,导致您看到的奇怪行为。首先,在 Python 2.7print中既是关键字又是内置函数。(我不知道为什么,但我想可能是为了更接近 Python 3.0,其中print显然是内置函数而不是关键字。)因此构造了一个正则表达式,可以将 print 作为关键字或内置函数进行匹配。但是为什么它有时匹配一个,有时匹配另一个呢?

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

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

于 2012-05-26T10:16:49.783 回答