1

关于由 ast 模块计算的 lineno 偏移量,我有一些不明白的地方。通常当我得到某个 ast 对象的 lineno 时,它会给我遇到该对象的第一行。

例如在下面的例子中,foo 的 lin

st='def foo():\n    print "hello"'
import ast
print ast.parse(st).body[0].lineno 
print ast.parse(st).body[0].body[0].lineno

将为函数 foo返回1并为 hello world 打印输出返回2

但是,如果我解析多行文档字符串(ast.Expr),则提供的 lineno 是最后一行。

st='def foo():\n    """\n    Test\n    """'   
import ast
print ast.parse(st).body[0].lineno 
print ast.parse(st).body[0].body[0].lineno

结果仍然是函数的第1行,但文档字符串的结果将是第4行。我原以为它会在第2行,因为那是文档字符串开始的时候。

我想我要问的是是否有办法始终获得包括 ast.Expr 在内的所有 ast 对象的第一个 lineno 。

4

1 回答 1

0

AST 的源位置还有很多不足之处,但其中很多都可以通过ASTTokens库获得,该库使用更有用的位置信息注释 AST 节点。在您的示例中:

import asttokens
st='def foo():\n    """\n    Test\n    """'
atok = asttokens.ASTTokens(st, parse=True)

print atok.tree.body[0].first_token.start[0]
print atok.tree.body[0].body[0].first_token.start[0]

根据需要打印12。也许更有趣的是,

print atok.get_text_range(atok.tree.body[0])
print atok.get_text_range(atok.tree.body[0].body[0])

打印与节点对应的源文本范围:在本例中为 (0,35) 和 (15,35)。

于 2016-12-14T02:58:46.877 回答