标记/取消标记python字符串代码,使其与交互模式兼容

Posted

技术标签:

【中文标题】标记/取消标记python字符串代码,使其与交互模式兼容【英文标题】:tokenize/untokenize python string code so that it is compatible with interactive-mode 【发布时间】:2014-02-07 08:37:59 【问题描述】:

我有类似的python代码具有这种结构

def main:

    ''' comment '''
    if True:
        print "do"
    print "done

此代码与交互模式不兼容(例如,如果我在交互会话中复制/粘贴它)。为此,它需要:

def main:
    ''' comment '''
    if True:
        print "do"

    print "done"

否则交互模式会因缩进问题而中断。

您知道使用 generate_token / unkenize 链转换代码的简单方法吗?我有点迷失在 NL / NEWLINE / INDENT / DEDENT 语义中。

我发现这个Script to remove Python comments/docstrings 删除了 cmets/docstrings。它看起来非常适合我的问题,但它无法将其整理出来以在复杂代码上获得干净的输出。

【问题讨论】:

我认为您可以删除所有空行且不在字符串中的行。 没有。删除空行将使其适用于 def main: / '''comment''' 但它不会在 print "do" 后添加一行 【参考方案1】:

我能想到的最好的(解决了我的问题)

def _python_interactive_indent(self, code):
    prev_toktype = tokenize.INDENT
    first_line = None
    last_lineno = -1
    last_col = 0

    output = ''

    tokgen = tokenize.generate_tokens(StringIO.StringIO(code).readline)
    indent = 0
    hasNL = False
    prefixed = False
    for toktype, ttext, (slineno, scol), (elineno, ecol), ltext in tokgen:
        done = False
        if toktype == tokenize.INDENT:
            indent = indent + 1
        if toktype == tokenize.DEDENT:
            indent = indent - 1
        if slineno > last_lineno:
            last_col = 0
        if not done and toktype == tokenize.NL:
            hasNL = True
            done = True
        if not done and toktype == tokenize.COMMENT:
            done = True
        if not done and toktype == tokenize.STRING and prev_toktype == tokenize.INDENT:
            done = True
        if not done and hasNL and toktype != tokenize.DEDENT and toktype != tokenize.INDENT:
            hasNL = False
            output = output + ("    " * indent) + '\n'
            output += "    " * indent
            prefixed = True
        if not done:
            if not prefixed and scol > last_col:
                output += (" " * (scol - last_col))
            output += (ttext)
        prefixed = False
        prev_toktype = toktype
        last_col = ecol
        last_lineno = elineno
    return output

【讨论】:

以上是关于标记/取消标记python字符串代码,使其与交互模式兼容的主要内容,如果未能解决你的问题,请参考以下文章

parent.navigate 仅适用于 IE。我必须有啥替代方法才能使其与其他浏览器一起使用?

从 markerClusterer 中删除标记

如何使标记完美重叠,使其不会在同一端出现两次?

从字符串中删除 HTML 标记

F# 线程中的取消标记

WPF TextBox:取消放置操作会留下插入标记