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を返します。

ただし、複数行の 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行目になります。docstring が始まるのは 2 行目なので、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 に答える