Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Ast.Expr类型的Ast解析_Python_Abstract Syntax Tree_Expr - Fatal编程技术网

Python Ast.Expr类型的Ast解析

Python Ast.Expr类型的Ast解析,python,abstract-syntax-tree,expr,Python,Abstract Syntax Tree,Expr,关于ast模块正在计算的lineno偏移量,有一些我不理解的地方。通常,当我得到某个ast对象的行号时,它会给出该对象遇到的第一行 例如,在下面的例子中,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模块正在计算的lineno偏移量,有一些我不理解的地方。通常,当我得到某个ast对象的行号时,它会给出该对象遇到的第一行

例如,在下面的例子中,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

但是,如果我分析一个多行docstring 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行,但docstring的结果是第4行。我希望它在第2行,因为那是docstring开始的时候


我想我要问的是,是否有一种方法可以始终获取所有ast对象(包括ast.Expr)的第一行编号

AST的源位置还有很多需要改进的地方,但其中很多都是由库提供的,库用更有用的位置信息注释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]
根据需要打印1和2。也许更有趣的是

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

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

我很确定它通常不会给出第一行,而是会考虑包含反斜杠、括号和三引号后的第一个虚拟行的一部分的最后一个物理行。换句话说,在异常回溯中看到多行表达式最后一行的规则是一样的,但我怀疑文档中的任何地方都记录了这一点,它只是说这是源文本的行。如果您想深入研究CPython 2.7源代码,它应该在ast.c中设置n_lineno,可能是通过在每个节点类型的一个标头中定义的宏。或者那可能太晚了;您可能需要查看创建CST作为AST输入的生成代码。