IndentationError 在 `ast.parse` 和 `ast.walk` 的一个函数中,该函数是类中的一个方法

fin*_*oot -1 python parsing indentation abstract-syntax-tree static-code-analysis

我想我知道IndentationError 中IndentationError描述的类似的常见原因:例如,unindent 不匹配任何外部缩进级别。这不适用于这里。

另外,我知道,textwrap.dedent但感觉这里不是正确的方法?


如果我有一个“正规”的功能,我可以做ast.parseast.walk这样的:

import ast
import inspect

def a():
    pass

code = inspect.getsource(a)
nodes = ast.walk(ast.parse(code))
for node in nodes:
    ...
Run Code Online (Sandbox Code Playgroud)

但是,如果函数是类中的方法,例如:

class B:
    def c(self):
        pass

code = inspect.getsource(B.c)
nodes = ast.walk(ast.parse(code))
Run Code Online (Sandbox Code Playgroud)

我得到:

IndentationError: unexpected indent
Run Code Online (Sandbox Code Playgroud)

我想这是有道理的,因为B.c 缩进了一级。那么我ast.parseast.walk这里怎么办呢?

Err*_*rse 6

这是因为您抓住了方法而不是尝试在不撤消缩进的情况下走它。你的班级是:

class B:
    def c(self):
        pass

code = inspect.getsource(B.c)
nodes = ast.walk(ast.parse(code))
Run Code Online (Sandbox Code Playgroud)

如果您打印,code您会看到:

    def c(self):
        pass
Run Code Online (Sandbox Code Playgroud)

注意:上面的代码有一个缩进。您需要取消缩进:

import inspect
import ast
import textwrap
class B:
    def c(self):
        pass
code = textwrap.dedent(inspect.getsource(B.c))
nodes = ast.walk(ast.parse(code))
Run Code Online (Sandbox Code Playgroud)

  • `ast` 旨在从文本中读取有效的 Python 代码。您解析了一个有效代码的子集,然后将其作为文本传递给 `ast`,但由于您只抓取了部分代码,因此它不再有效(缩进错误)。 (2认同)
  • 我应该补充一点,这将适用于您提出的问题,但是如果您想对 AST 进行修改并将其编译成一个新函数,那么诸如类的上下文将很重要,而这个解决方案是不够的。 (2认同)