ast
— 抽象语法树¶
源代码: Lib/ast.py
ast
模块帮助 Python 程序处理 Python 语法的抽象语法树。抽象语法或许会随着 Python 的更新发布而改变;该模块能够帮助理解当前语法在编程层面的样貌。
抽象语法树可通过将 ast.PyCF_ONLY_AST
作为旗标传递给 compile()
内置函数来生成,或是使用此模块中提供的 parse()
辅助函数。返回结果将是一个对象树,其中的类都继承自 ast.AST
。抽象语法树可被内置的 compile()
函数编译为一个 Python 代码对象。
抽象文法¶
抽象文法目前定义如下:
-- ASDL's 4 builtin types are:
-- identifier, int, string, constant
module Python
{
mod = Module(stmt* body, type_ignore* type_ignores)
| Interactive(stmt* body)
| Expression(expr body)
| FunctionType(expr* argtypes, expr returns)
stmt = FunctionDef(identifier name, arguments args,
stmt* body, expr* decorator_list, expr? returns,
string? type_comment)
| AsyncFunctionDef(identifier name, arguments args,
stmt* body, expr* decorator_list, expr? returns,
string? type_comment)
| ClassDef(identifier name,
expr* bases,
keyword* keywords,
stmt* body,
expr* decorator_list)
| Return(expr? value)
| Delete(expr* targets)
| Assign(expr* targets, expr value, string? type_comment)
| AugAssign(expr target, operator op, expr value)
-- 'simple' indicates that we annotate simple name without parens
| AnnAssign(expr target, expr annotation, expr? value, int simple)
-- use 'orelse' because else is a keyword in target languages
| For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)
| AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)
| While(expr test, stmt* body, stmt* orelse)
| If(expr test, stmt* body, stmt* orelse)
| With(withitem* items, stmt* body, string? type_comment)
| AsyncWith(withitem* items, stmt* body, string? type_comment)
| Match(expr subject, match_case* cases)
| Raise(expr? exc, expr? cause)
| Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)
| TryStar(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)
| Assert(expr test, expr? msg)
| Import(alias* names)
| ImportFrom(identifier? module, alias* names, int? level)
| Global(identifier* names)
| Nonlocal(identifier* names)
| Expr(expr value)
| Pass | Break | Continue
-- col_offset is the byte offset in the utf8 string the parser uses
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
-- BoolOp() can use left & right?
expr = BoolOp(boolop op, expr* values)
| NamedExpr(expr target, expr value)
| BinOp(expr left, operator op, expr right)
| UnaryOp(unaryop op, expr operand)
| Lambda(arguments args, expr body)
| IfExp(expr test, expr body, expr orelse)
| Dict(expr* keys, expr* values)
| Set(expr* elts)
| ListComp(expr elt, comprehension* generators)
| SetComp(expr elt, comprehension* generators)
| DictComp(expr key, expr value, comprehension* generators)
| GeneratorExp(expr elt, comprehension* generators)
-- the grammar constrains where yield expressions can occur
| Await(expr value)
| Yield(expr? value)
| YieldFrom(expr value)
-- need sequences for compare to distinguish between
-- x < 4 < 3 and (x < 4) < 3
| Compare(expr left, cmpop* ops, expr* comparators)
| Call(expr func, expr* args, keyword* keywords)
| FormattedValue(expr value, int conversion, expr? format_spec)
| JoinedStr(expr* values)
| Constant(constant value, string? kind)
-- the following expression can appear in assignment context
| Attribute(expr value, identifier attr, expr_context ctx)
| Subscript(expr value, expr slice, expr_context ctx)
| Starred(expr value, expr_context ctx)
| Name(identifier id, expr_context ctx)
| List(expr* elts, expr_context ctx)
| Tuple(expr* elts, expr_context ctx)
-- can appear only in Subscript
| Slice(expr? lower, expr? upper, expr? step)
-- col_offset is the byte offset in the utf8 string the parser uses
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
expr_context = Load | Store | Del
boolop = And | Or
operator = Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift
| RShift | BitOr | BitXor | BitAnd | FloorDiv
unaryop = Invert | Not | UAdd | USub
cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn
comprehension = (expr target, expr iter, expr* ifs, int is_async)
excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body)
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
arguments = (arg* posonlyargs, arg* args, arg? vararg, arg* kwonlyargs,
expr* kw_defaults, arg? kwarg, expr* defaults)
arg = (identifier arg, expr? annotation, string? type_comment)
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
-- keyword arguments supplied to call (NULL identifier for **kwargs)
keyword = (identifier? arg, expr value)
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
-- import name with optional 'as' alias.
alias = (identifier name, identifier? asname)
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
withitem = (expr context_expr, expr? optional_vars)
match_case = (pattern pattern, expr? guard, stmt* body)
pattern = MatchValue(expr value)
| MatchSingleton(constant value)
| MatchSequence(pattern* patterns)
| MatchMapping(expr* keys, pattern* patterns, identifier? rest)
| MatchClass(expr cls, pattern* patterns, identifier* kwd_attrs, pattern* kwd_patterns)
| MatchStar(identifier? name)
-- The optional "rest" MatchMapping parameter handles capturing extra mapping keys
| MatchAs(pattern? pattern, identifier? name)
| MatchOr(pattern* patterns)
attributes (int lineno, int col_offset, int end_lineno, int end_col_offset)
type_ignore = TypeIgnore(int lineno, string tag)
}
节点类¶
- class ast.AST¶
This is the base of all AST node classes. The actual node classes are derived from the
Parser/Python.asdl
file, which is reproduced above. They are defined in the_ast
C module and re-exported inast
.抽象语法定义的每个左侧符号(比方说,
ast.stmt
或者ast.expr
)定义了一个类。另外,在抽象语法定义的右侧,对每一个构造器也定义了一个类;这些类继承自树左侧的类。比如,ast.BinOp
继承自ast.expr
。对于多分支产生式(也就是”和规则”),树右侧的类是抽象的;只有特定构造器结点的实例能被构造。- _fields¶
每个具体类都有个属性
_fields
, 用来给出所有子节点的名字。每个具体类的实例对它每个子节点都有一个属性,对应类型如文法中所定义。比如,
ast.BinOp
的实例有个属性left
,类型是ast.expr
.如果这些属性在文法中标记为可选(使用问号),对应值可能会是
None
。如果这些属性有零或多个(用星号标记),对应值会用 Python 的列表来表示。所有可能的属性必须在用compile()
编译得到 AST 时给出,且是有效的值。
- lineno¶
- col_offset¶
- end_lineno¶
- end_col_offset¶
ast.expr
和ast.stmt
子类的实例有lineno
、col_offset
、end_lineno
和end_col_offset
属性。lineno
和end_lineno
是源文本跨度的第一行和最后一行的编号(1-索引,所以第一行是 行1),而col_offset
和end_col_offset
是生成该节点的第一个和最后一个形符的相应 UTF-8 字节偏差。UTF-8 的偏移量被记录下来,因为分析器内部使用 UTF-8。请注意,编译器不要求结束位置,因此是可选的。末端偏移量是在最后一个符号之后,例如可以用
source_line[node.col_offset : node.end_col_offset]
得到单行表达式节点的源片段。
类的构造器
ast.T
像下面这样解析它的参数:如果有位置参数,它们必须和
T._fields
中的元素一样多;他们会像这些名字的属性一样被赋值。如果有关键字参数,它们必须被设为和给定值同名的属性。
比方说,要创建和填充节点
ast.UnaryOp
,你得用node = ast.UnaryOp() node.op = ast.USub() node.operand = ast.Constant() node.operand.value = 5 node.operand.lineno = 0 node.operand.col_offset = 0 node.lineno = 0 node.col_offset = 0
或者更紧凑点
node = ast.UnaryOp(ast.USub(), ast.Constant(5, lineno=0, col_offset=0), lineno=0, col_offset=0)
在 3.8 版更改: 类 ast.Constant
现用于所有常量。
在 3.9 版更改: 简单的索引用其值表示,扩展的切片用元组表示。
3.8 版后已移除: 旧的类 ast.Num
、ast.Str
、ast.Bytes
、ast.NameConstant
和 ast.Ellipsis
仍然可用,但它们将在未来的 Python 版本中被删除。在此期间,实例化它们将返回一个不同类的实例。
3.9 版后已移除: 旧的类 ast.Index
和 ast.ExtSlice
仍然可用,但它们将在未来的 Python 版本中被移除。在此期间,实例化它们将返回一个不同类的实例。
备注
这里显示的具体节点类的描述最初是从神奇的 绿色树蛇 项目及其所有贡献者那里改编的。
字面值¶
- class ast.Constant(value)¶
一个常量值。
Constant
字面的value
属性包含它所代表的 Python 对象。所代表的值可以是简单的类型,如数字、字符串或None
,也可以是不可变的容器类型(tuple 和 frozenset),如果它们的所有元素都是常数的话。>>> print(ast.dump(ast.parse('123', mode='eval'), indent=4)) Expression( body=Constant(value=123))
- class ast.FormattedValue(value, conversion, format_spec)¶
代表 f-string 中单一格式化字段的节点。如果字符串包含一个单一的格式化字段,而没有其他内容,那么该节点可以被隔离,否则它将出现在
JoinedStr
中。value
是任何表达式节点(如字面值、变量或函数调用)。conversion
是整数:-1:没有格式化
115:
!s
字符串格式化114:
!r
repr 格式化97:
!a
ascii 格式化
format_spec
是一个JoinedStr
节点,代表值的格式化,如果没有指定格式,则为None
。conversion
和format_spec
都可以同时设置。
- class ast.JoinedStr(values)¶
f-string,包括一系列的
FormattedValue
和Constant
节点。>>> print(ast.dump(ast.parse('f"sin({a}) is {sin(a):.3}"', mode='eval'), indent=4)) Expression( body=JoinedStr( values=[ Constant(value='sin('), FormattedValue( value=Name(id='a', ctx=Load()), conversion=-1), Constant(value=') is '), FormattedValue( value=Call( func=Name(id='sin', ctx=Load()), args=[ Name(id='a', ctx=Load())], keywords=[]), conversion=-1, format_spec=JoinedStr( values=[ Constant(value='.3')]))]))
- class ast.List(elts, ctx)¶
- class ast.Tuple(elts, ctx)¶
一个列表或元组。
elts
持有代表其元素的节点列表。如果容器是一个赋值目标(即(x,y)=something
),ctx
是Store
,否则Load
。>>> print(ast.dump(ast.parse('[1, 2, 3]', mode='eval'), indent=4)) Expression( body=List( elts=[ Constant(value=1), Constant(value=2), Constant(value=3)], ctx=Load())) >>> print(ast.dump(ast.parse('(1, 2, 3)', mode='eval'), indent=4)) Expression( body=Tuple( elts=[ Constant(value=1), Constant(value=2), Constant(value=3)], ctx=Load()))
- class ast.Set(elts)¶
集合。
elts
持有代表该集合元素的节点列表。>>> print(ast.dump(ast.parse('{1, 2, 3}', mode='eval'), indent=4)) Expression( body=Set( elts=[ Constant(value=1), Constant(value=2), Constant(value=3)]))
- class ast.Dict(keys, values)¶
字典。
keys
和values
分别持有代表其键和值的节点列表,顺序匹配(当调用dictionary.keys()
和dictionary.values()
时将会返回)。当使用字典字元进行字典解包时,要展开的表达式在
values
列表中,在keys
的相应位置有一个None
。>>> print(ast.dump(ast.parse('{"a":1, **d}', mode='eval'), indent=4)) Expression( body=Dict( keys=[ Constant(value='a'), None], values=[ Constant(value=1), Name(id='d', ctx=Load())]))
变量¶
- class ast.Name(id, ctx)¶
变量名称。
id
持有作为字符串的名称,ctx
是以下类型之一。
- class ast.Load¶
- class ast.Store¶
- class ast.Del¶
变量引用可以用来加载变量的值、给它分配新的值或者删除它。变量引用被赋予一个上下文以区分这些情况。
>>> print(ast.dump(ast.parse('a'), indent=4)) Module( body=[ Expr( value=Name(id='a', ctx=Load()))], type_ignores=[]) >>> print(ast.dump(ast.parse('a = 1'), indent=4)) Module( body=[ Assign( targets=[ Name(id='a', ctx=Store())], value=Constant(value=1))], type_ignores=[]) >>> print(ast.dump(ast.parse('del a'), indent=4)) Module( body=[ Delete( targets=[ Name(id='a', ctx=Del())])], type_ignores=[])
- class ast.Starred(value, ctx)¶
*var
的变量引用。value
持有变量,通常是一个Name
节点。当建立一个带有*args
的Call
节点时,必须使用这种类型。>>> print(ast.dump(ast.parse('a, *b = it'), indent=4)) Module( body=[ Assign( targets=[ Tuple( elts=[ Name(id='a', ctx=Store()), Starred( value=Name(id='b', ctx=Store()), ctx=Store())], ctx=Store())], value=Name(id='it', ctx=Load()))], type_ignores=[])
表达式¶
- class ast.Expr(value)¶
当一个表达式,比如一个函数调用,本身作为一个语句出现,其返回值没有被使用或存储,它被包裹在这个容器中。
value
容纳本节中的一个其他节点,Constant
、Name
、Lambda
、Yield
或YieldFrom
节点。>>> print(ast.dump(ast.parse('-a'), indent=4)) Module( body=[ Expr( value=UnaryOp( op=USub(), operand=Name(id='a', ctx=Load())))], type_ignores=[])
- class ast.UnaryOp(op, operand)¶
一元运算。
op
是运算符,operand
是任何表达式节点。
- class ast.UAdd¶
- class ast.USub¶
- class ast.Not¶
- class ast.Invert¶
一元运算形符。
Not
是not
关键字、Invert
是~
运算符。>>> print(ast.dump(ast.parse('not x', mode='eval'), indent=4)) Expression( body=UnaryOp( op=Not(), operand=Name(id='x', ctx=Load())))
- class ast.BinOp(left, op, right)¶
二元运算(如加法或除法)。
op
是运算符,left
和right
是任何表达式节点。>>> print(ast.dump(ast.parse('x + y', mode='eval'), indent=4)) Expression( body=BinOp( left=Name(id='x', ctx=Load()), op=Add(), right=Name(id='y', ctx=Load())))
- class ast.Add¶
- class ast.Sub¶
- class ast.Mult¶
- class ast.Div¶
- class ast.FloorDiv¶
- class ast.Mod¶
- class ast.Pow¶
- class ast.LShift¶
- class ast.RShift¶
- class ast.BitOr¶
- class ast.BitXor¶
- class ast.BitAnd¶
- class ast.MatMult¶
二元运算符的形符。
- class ast.BoolOp(op, values)¶
一个布尔运算,’or’ 或 ‘and’。
op
是Or
或And
。values
是所涉及的值。具有相同操作符的连续操作,如a or b or c
,会被折叠成一个具有几个值的节点。这不包括
not
,它是一个UnaryOp
。>>> print(ast.dump(ast.parse('x or y', mode='eval'), indent=4)) Expression( body=BoolOp( op=Or(), values=[ Name(id='x', ctx=Load()), Name(id='y', ctx=Load())]))
- class ast.Compare(left, ops, comparators)¶
两个或多个值的比较。
left
是比较中的第一个值,ops
是运算符的列表,comparators
是比较中第一个元素之后的值列表。>>> print(ast.dump(ast.parse('1 <= a < 10', mode='eval'), indent=4)) Expression( body=Compare( left=Constant(value=1), ops=[ LtE(), Lt()], comparators=[ Name(id='a', ctx=Load()), Constant(value=10)]))
- class ast.Eq¶
- class ast.NotEq¶
- class ast.Lt¶
- class ast.LtE¶
- class ast.Gt¶
- class ast.GtE¶
- class ast.Is¶
- class ast.IsNot¶
- class ast.In¶
- class ast.NotIn¶
比较运算形符。
- class ast.Call(func, args, keywords, starargs, kwargs)¶
一个函数调用。
func
是函数,通常是一个Name
或Attribute
对象。参数:args
持有一个由位置传递的参数列表。keywords
持有一个keyword
对象的列表,代表由 keyword 传递的参数。
当创建一个
Call
节点时,args
和keywords
是必须的,但它们可以是空列表。starargs
和kwargs
是可选的。>>> print(ast.dump(ast.parse('func(a, b=c, *d, **e)', mode='eval'), indent=4)) Expression( body=Call( func=Name(id='func', ctx=Load()), args=[ Name(id='a', ctx=Load()), Starred( value=Name(id='d', ctx=Load()), ctx=Load())], keywords=[ keyword( arg='b', value=Name(id='c', ctx=Load())), keyword( value=Name(id='e', ctx=Load()))]))
- class ast.keyword(arg, value)¶
一个函数调用或类定义的关键字参数。
arg
是参数名称的原始字符串,value
是要传入的节点。
- class ast.IfExp(test, body, orelse)¶
一个表达式,如
a if b else c
。每个字段持有一个节点,所以在下面的例子中,三个都是Name
节点”>>> print(ast.dump(ast.parse('a if b else c', mode='eval'), indent=4)) Expression( body=IfExp( test=Name(id='b', ctx=Load()), body=Name(id='a', ctx=Load()), orelse=Name(id='c', ctx=Load())))
- class ast.Attribute(value, attr, ctx)¶
属性访问,例如:
d.keys
。value
是一个节点,通常是Name
。attr
是一个裸字符串,给出属性的名称,ctx
是Load
、Store
或Del
,根据属性的操作方式。>>> print(ast.dump(ast.parse('snake.colour', mode='eval'), indent=4)) Expression( body=Attribute( value=Name(id='snake', ctx=Load()), attr='colour', ctx=Load()))
- class ast.NamedExpr(target, value)¶
一个命名的表达式。这个 AST 节点是由赋值表达式运算符(也被称为海象运算符)产生的。相对于
Assign
节点,其中第一个参数可以是多个节点,在这种情况下,target
和value
都必须是单个节点。>>> print(ast.dump(ast.parse('(x := 4)', mode='eval'), indent=4)) Expression( body=NamedExpr( target=Name(id='x', ctx=Store()), value=Constant(value=4)))
下标¶
- class ast.Subscript(value, slice, ctx)¶
一个下标,例如
l[1]
。value
是下标的对象(通常是序列或映射)。slice
是一个索引、切片或键。它可以是一个Tuple
并包含一个Slice
。ctx
是Load
、Store
或Del
,根据对下标执行的操作。>>> print(ast.dump(ast.parse('l[1:2, 3]', mode='eval'), indent=4)) Expression( body=Subscript( value=Name(id='l', ctx=Load()), slice=Tuple( elts=[ Slice( lower=Constant(value=1), upper=Constant(value=2)), Constant(value=3)], ctx=Load()), ctx=Load()))
- class ast.Slice(lower, upper, step)¶
常规切片(形式为
lower:upper
或lower:upper:step
)。只能出现在subscript
的 slice 字段内,可以直接出现,也可以作为Tuple
的一个元素出现。>>> print(ast.dump(ast.parse('l[1:2]', mode='eval'), indent=4)) Expression( body=Subscript( value=Name(id='l', ctx=Load()), slice=Slice( lower=Constant(value=1), upper=Constant(value=2)), ctx=Load()))
解析式¶
- class ast.ListComp(elt, generators)¶
- class ast.SetComp(elt, generators)¶
- class ast.GeneratorExp(elt, generators)¶
- class ast.DictComp(key, value, generators)¶
列表和集合的解析式,生成器表达式和字典的解析式。
elt``(或 ``key
和value
)是一个单一的节点,代表每个项将被评估的部分。generators
是一个comprehension
节点的列表。>>> print(ast.dump(ast.parse('[x for x in numbers]', mode='eval'), indent=4)) Expression( body=ListComp( elt=Name(id='x', ctx=Load()), generators=[ comprehension( target=Name(id='x', ctx=Store()), iter=Name(id='numbers', ctx=Load()), ifs=[], is_async=0)])) >>> print(ast.dump(ast.parse('{x: x**2 for x in numbers}', mode='eval'), indent=4)) Expression( body=DictComp( key=Name(id='x', ctx=Load()), value=BinOp( left=Name(id='x', ctx=Load()), op=Pow(), right=Constant(value=2)), generators=[ comprehension( target=Name(id='x', ctx=Store()), iter=Name(id='numbers', ctx=Load()), ifs=[], is_async=0)])) >>> print(ast.dump(ast.parse('{x for x in numbers}', mode='eval'), indent=4)) Expression( body=SetComp( elt=Name(id='x', ctx=Load()), generators=[ comprehension( target=Name(id='x', ctx=Store()), iter=Name(id='numbers', ctx=Load()), ifs=[], is_async=0)]))
- class ast.comprehension(target, iter, ifs, is_async)¶
在一个解析式中的一个
for
子句。target
是每个元素的引用 - 通常是一个Name
或Tuple
节点。iter
是要迭代的对象。ifs
是测试表达式的列表:每个for
子句可以有多个ifs
。is_async
表示一个解析式是异步的(使用async for
而不是for
)。其值是一个整数(0 或 1)。>>> print(ast.dump(ast.parse('[ord(c) for line in file for c in line]', mode='eval'), ... indent=4)) # Multiple comprehensions in one. Expression( body=ListComp( elt=Call( func=Name(id='ord', ctx=Load()), args=[ Name(id='c', ctx=Load())], keywords=[]), generators=[ comprehension( target=Name(id='line', ctx=Store()), iter=Name(id='file', ctx=Load()), ifs=[], is_async=0), comprehension( target=Name(id='c', ctx=Store()), iter=Name(id='line', ctx=Load()), ifs=[], is_async=0)])) >>> print(ast.dump(ast.parse('(n**2 for n in it if n>5 if n<10)', mode='eval'), ... indent=4)) # generator comprehension Expression( body=GeneratorExp( elt=BinOp( left=Name(id='n', ctx=Load()), op=Pow(), right=Constant(value=2)), generators=[ comprehension( target=Name(id='n', ctx=Store()), iter=Name(id='it', ctx=Load()), ifs=[ Compare( left=Name(id='n', ctx=Load()), ops=[ Gt()], comparators=[ Constant(value=5)]), Compare( left=Name(id='n', ctx=Load()), ops=[ Lt()], comparators=[ Constant(value=10)])], is_async=0)])) >>> print(ast.dump(ast.parse('[i async for i in soc]', mode='eval'), ... indent=4)) # Async comprehension Expression( body=ListComp( elt=Name(id='i', ctx=Load()), generators=[ comprehension( target=Name(id='i', ctx=Store()), iter=Name(id='soc', ctx=Load()), ifs=[], is_async=1)]))
语句¶
- class ast.Assign(targets, value, type_comment)¶
赋值。
targets
是一个节点列表,value
是一个单一节点。targets
中的多个节点代表给每个节点分配相同的值。解包是通过在targets
内放置一个Tuple
或List
来表示。- type_comment¶
type_comment
是一个可选的字符串,其中的类型注释是一个注释。
>>> print(ast.dump(ast.parse('a = b = 1'), indent=4)) # Multiple assignment Module( body=[ Assign( targets=[ Name(id='a', ctx=Store()), Name(id='b', ctx=Store())], value=Constant(value=1))], type_ignores=[]) >>> print(ast.dump(ast.parse('a,b = c'), indent=4)) # Unpacking Module( body=[ Assign( targets=[ Tuple( elts=[ Name(id='a', ctx=Store()), Name(id='b', ctx=Store())], ctx=Store())], value=Name(id='c', ctx=Load()))], type_ignores=[])
- class ast.AnnAssign(target, annotation, value, simple)¶
一个带有类型注释的赋值。
target
是一个单一的节点,可以是Name
、Attribute
或一个Subscript
。annotation
是注释,例如Constant
或Name
节点。value
是一个单一的可选节点。simple
是一个布尔整数,对于target
中的Name
节点,设置为 True,不出现在括号之间,因此是纯名称,不是表达式。>>> print(ast.dump(ast.parse('c: int'), indent=4)) Module( body=[ AnnAssign( target=Name(id='c', ctx=Store()), annotation=Name(id='int', ctx=Load()), simple=1)], type_ignores=[]) >>> print(ast.dump(ast.parse('(a): int = 1'), indent=4)) # Annotation with parenthesis Module( body=[ AnnAssign( target=Name(id='a', ctx=Store()), annotation=Name(id='int', ctx=Load()), value=Constant(value=1), simple=0)], type_ignores=[]) >>> print(ast.dump(ast.parse('a.b: int'), indent=4)) # Attribute annotation Module( body=[ AnnAssign( target=Attribute( value=Name(id='a', ctx=Load()), attr='b', ctx=Store()), annotation=Name(id='int', ctx=Load()), simple=0)], type_ignores=[]) >>> print(ast.dump(ast.parse('a[1]: int'), indent=4)) # Subscript annotation Module( body=[ AnnAssign( target=Subscript( value=Name(id='a', ctx=Load()), slice=Constant(value=1), ctx=Store()), annotation=Name(id='int', ctx=Load()), simple=0)], type_ignores=[])
- class ast.AugAssign(target, op, value)¶
增强的赋值,如
a += 1
。在下面的例子中,target
是x
的一个Name
节点(有Store
上下文),op
是Add
,value
是一个Constant
,值为 1。与
Assign
的 targets 不同,target
属性不能是Tuple
或List
类。>>> print(ast.dump(ast.parse('x += 2'), indent=4)) Module( body=[ AugAssign( target=Name(id='x', ctx=Store()), op=Add(), value=Constant(value=2))], type_ignores=[])
- class ast.Raise(exc, cause)¶
raise
语句。exc
是要引发的异常对象,通常是Call
或Name
,或None
用于独立的raise
。cause
是raise x from y
中y
的可选部分。>>> print(ast.dump(ast.parse('raise x from y'), indent=4)) Module( body=[ Raise( exc=Name(id='x', ctx=Load()), cause=Name(id='y', ctx=Load()))], type_ignores=[])
- class ast.Assert(test, msg)¶
断言。
test
持有条件,例如Compare
节点。msg
持有失败信息。>>> print(ast.dump(ast.parse('assert x,y'), indent=4)) Module( body=[ Assert( test=Name(id='x', ctx=Load()), msg=Name(id='y', ctx=Load()))], type_ignores=[])
- class ast.Delete(targets)¶
代表一个
del
语句。targets
是一个节点列表,例如Name
、Attribute
或Subscript
的节点。>>> print(ast.dump(ast.parse('del x,y,z'), indent=4)) Module( body=[ Delete( targets=[ Name(id='x', ctx=Del()), Name(id='y', ctx=Del()), Name(id='z', ctx=Del())])], type_ignores=[])
- class ast.Pass¶
pass
语句。>>> print(ast.dump(ast.parse('pass'), indent=4)) Module( body=[ Pass()], type_ignores=[])
其他只适用于函数或循环内部的语句在其他章节中描述。
Imports¶
- class ast.Import(names)¶
导入语句。
names
是一个alias
节点的列表。>>> print(ast.dump(ast.parse('import x,y,z'), indent=4)) Module( body=[ Import( names=[ alias(name='x'), alias(name='y'), alias(name='z')])], type_ignores=[])
- class ast.ImportFrom(module, names, level)¶
代表
from x import y
。module
是 ‘from’ 名称的原始字符串,没有任何前导点,或None
用于诸如from . foo
的语句。level
是一个整数,表示相对导入的级别(0 表示绝对导入)。>>> print(ast.dump(ast.parse('from y import x,y,z'), indent=4)) Module( body=[ ImportFrom( module='y', names=[ alias(name='x'), alias(name='y'), alias(name='z')], level=0)], type_ignores=[])
- class ast.alias(name, asname)¶
两个参数都是名字的原始字符串。如果要使用常规名称,
asname
可以是None
。>>> print(ast.dump(ast.parse('from ..foo.bar import a as b, c'), indent=4)) Module( body=[ ImportFrom( module='foo.bar', names=[ alias(name='a', asname='b'), alias(name='c')], level=2)], type_ignores=[])
控制流¶
备注
像 else
这样的可选子句,如果不存在,就会被存储为一个空列表。
- class ast.If(test, body, orelse)¶
if
语句。test
持有一个节点,例如Compare
节点。body
和orelse
分别持有一个节点的列表。elif
子句在 AST 中没有特殊的表示方法,而是作为额外的If
节点出现在前一个子句的orelse
部分。>>> print(ast.dump(ast.parse(""" ... if x: ... ... ... elif y: ... ... ... else: ... ... ... """), indent=4)) Module( body=[ If( test=Name(id='x', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))], orelse=[ If( test=Name(id='y', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))], orelse=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.For(target, iter, body, orelse, type_comment)¶
A
for
loop.target
holds the variable(s) the loop assigns to, as a singleName
,Tuple
,List
,Attribute
orSubscript
node.iter
holds the item to be looped over, again as a single node.body
andorelse
contain lists of nodes to execute. Those inorelse
are executed if the loop finishes normally, rather than via abreak
statement.- type_comment¶
type_comment
是一个可选的字符串,其中的类型注释是一个注释。
>>> print(ast.dump(ast.parse(""" ... for x in y: ... ... ... else: ... ... ... """), indent=4)) Module( body=[ For( target=Name(id='x', ctx=Store()), iter=Name(id='y', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))], orelse=[ Expr( value=Constant(value=Ellipsis))])], type_ignores=[])
- class ast.While(test, body, orelse)¶
while
循环。test
持有条件,例如Compare
节点。>> print(ast.dump(ast.parse(""" ... while x: ... ... ... else: ... ... ... """), indent=4)) Module( body=[ While( test=Name(id='x', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))], orelse=[ Expr( value=Constant(value=Ellipsis))])], type_ignores=[])
- class ast.Break¶
- class ast.Continue¶
break
和continue
语句。>>> print(ast.dump(ast.parse("""\ ... for a in b: ... if a > 5: ... break ... else: ... continue ... ... """), indent=4)) Module( body=[ For( target=Name(id='a', ctx=Store()), iter=Name(id='b', ctx=Load()), body=[ If( test=Compare( left=Name(id='a', ctx=Load()), ops=[ Gt()], comparators=[ Constant(value=5)]), body=[ Break()], orelse=[ Continue()])], orelse=[])], type_ignores=[])
- class ast.Try(body, handlers, orelse, finalbody)¶
try
块。所有属性都是要执行的节点列表,除了handlers
,它是ExceptHandler
节点的列表。>>> print(ast.dump(ast.parse(""" ... try: ... ... ... except Exception: ... ... ... except OtherException as e: ... ... ... else: ... ... ... finally: ... ... ... """), indent=4)) Module( body=[ Try( body=[ Expr( value=Constant(value=Ellipsis))], handlers=[ ExceptHandler( type=Name(id='Exception', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))]), ExceptHandler( type=Name(id='OtherException', ctx=Load()), name='e', body=[ Expr( value=Constant(value=Ellipsis))])], orelse=[ Expr( value=Constant(value=Ellipsis))], finalbody=[ Expr( value=Constant(value=Ellipsis))])], type_ignores=[])
- class ast.TryStar(body, handlers, orelse, finalbody)¶
try
blocks which are followed byexcept*
clauses. The attributes are the same as forTry
but theExceptHandler
nodes inhandlers
are interpreted asexcept*
blocks rather thenexcept
.>>> print(ast.dump(ast.parse(""" ... try: ... ... ... except* Exception: ... ... ... """), indent=4)) Module( body=[ TryStar( body=[ Expr( value=Constant(value=Ellipsis))], handlers=[ ExceptHandler( type=Name(id='Exception', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))])], orelse=[], finalbody=[])], type_ignores=[])
- class ast.ExceptHandler(type, name, body)¶
一个单一的
except
子句。type
是它要匹配的异常类型,通常是Name
节点(或者None
是一个全面的except:
子句)。name
是一个原始字符串,用于保存异常的名称,如果子句中没有as foo
,则为None
。body
是一个节点的列表。>>> print(ast.dump(ast.parse("""\ ... try: ... a + 1 ... except TypeError: ... pass ... """), indent=4)) Module( body=[ Try( body=[ Expr( value=BinOp( left=Name(id='a', ctx=Load()), op=Add(), right=Constant(value=1)))], handlers=[ ExceptHandler( type=Name(id='TypeError', ctx=Load()), body=[ Pass()])], orelse=[], finalbody=[])], type_ignores=[])
- class ast.With(items, body, type_comment)¶
with
块。items
是一个代表上下文管理者的withitem
节点的列表,body
是上下文中缩进的块。- type_comment¶
type_comment
是一个可选的字符串,其中的类型注释是一个注释。
- class ast.withitem(context_expr, optional_vars)¶
with
区块中的单个上下文管理器。context_expr
是上下文管理器,通常是一个Call
节点。optional_vars
是Name
、Tuple
或List
的as foo
部分,如果不使用,则为None
。>>> print(ast.dump(ast.parse("""\ ... with a as b, c as d: ... something(b, d) ... """), indent=4)) Module( body=[ With( items=[ withitem( context_expr=Name(id='a', ctx=Load()), optional_vars=Name(id='b', ctx=Store())), withitem( context_expr=Name(id='c', ctx=Load()), optional_vars=Name(id='d', ctx=Store()))], body=[ Expr( value=Call( func=Name(id='something', ctx=Load()), args=[ Name(id='b', ctx=Load()), Name(id='d', ctx=Load())], keywords=[]))])], type_ignores=[])
Pattern matching¶
- class ast.Match(subject, cases)¶
A
match
statement.subject
holds the subject of the match (the object that is being matched against the cases) andcases
contains an iterable ofmatch_case
nodes with the different cases.
- class ast.match_case(pattern, guard, body)¶
A single case pattern in a
match
statement.pattern
contains the match pattern that the subject will be matched against. Note that theAST
nodes produced for patterns differ from those produced for expressions, even when they share the same syntax.The
guard
attribute contains an expression that will be evaluated if the pattern matches the subject.body
contains a list of nodes to execute if the pattern matches and the result of evaluating the guard expression is true.>>> print(ast.dump(ast.parse(""" ... match x: ... case [x] if x>0: ... ... ... case tuple(): ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchSequence( patterns=[ MatchAs(name='x')]), guard=Compare( left=Name(id='x', ctx=Load()), ops=[ Gt()], comparators=[ Constant(value=0)]), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchClass( cls=Name(id='tuple', ctx=Load()), patterns=[], kwd_attrs=[], kwd_patterns=[]), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.MatchValue(value)¶
A match literal or value pattern that compares by equality.
value
is an expression node. Permitted value nodes are restricted as described in the match statement documentation. This pattern succeeds if the match subject is equal to the evaluated value.>>> print(ast.dump(ast.parse(""" ... match x: ... case "Relevant": ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchValue( value=Constant(value='Relevant')), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.MatchSingleton(value)¶
A match literal pattern that compares by identity.
value
is the singleton to be compared against:None
,True
, orFalse
. This pattern succeeds if the match subject is the given constant.>>> print(ast.dump(ast.parse(""" ... match x: ... case None: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchSingleton(value=None), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.MatchSequence(patterns)¶
A match sequence pattern.
patterns
contains the patterns to be matched against the subject elements if the subject is a sequence. Matches a variable length sequence if one of the subpatterns is aMatchStar
node, otherwise matches a fixed length sequence.>>> print(ast.dump(ast.parse(""" ... match x: ... case [1, 2]: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchSequence( patterns=[ MatchValue( value=Constant(value=1)), MatchValue( value=Constant(value=2))]), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.MatchStar(name)¶
Matches the rest of the sequence in a variable length match sequence pattern. If
name
is notNone
, a list containing the remaining sequence elements is bound to that name if the overall sequence pattern is successful.>>> print(ast.dump(ast.parse(""" ... match x: ... case [1, 2, *rest]: ... ... ... case [*_]: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchSequence( patterns=[ MatchValue( value=Constant(value=1)), MatchValue( value=Constant(value=2)), MatchStar(name='rest')]), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchSequence( patterns=[ MatchStar()]), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.MatchMapping(keys, patterns, rest)¶
A match mapping pattern.
keys
is a sequence of expression nodes.patterns
is a corresponding sequence of pattern nodes.rest
is an optional name that can be specified to capture the remaining mapping elements. Permitted key expressions are restricted as described in the match statement documentation.This pattern succeeds if the subject is a mapping, all evaluated key expressions are present in the mapping, and the value corresponding to each key matches the corresponding subpattern. If
rest
is notNone
, a dict containing the remaining mapping elements is bound to that name if the overall mapping pattern is successful.>>> print(ast.dump(ast.parse(""" ... match x: ... case {1: _, 2: _}: ... ... ... case {**rest}: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchMapping( keys=[ Constant(value=1), Constant(value=2)], patterns=[ MatchAs(), MatchAs()]), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchMapping(keys=[], patterns=[], rest='rest'), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.MatchClass(cls, patterns, kwd_attrs, kwd_patterns)¶
A match class pattern.
cls
is an expression giving the nominal class to be matched.patterns
is a sequence of pattern nodes to be matched against the class defined sequence of pattern matching attributes.kwd_attrs
is a sequence of additional attributes to be matched (specified as keyword arguments in the class pattern),kwd_patterns
are the corresponding patterns (specified as keyword values in the class pattern).This pattern succeeds if the subject is an instance of the nominated class, all positional patterns match the corresponding class-defined attributes, and any specified keyword attributes match their corresponding pattern.
Note: classes may define a property that returns self in order to match a pattern node against the instance being matched. Several builtin types are also matched that way, as described in the match statement documentation.
>>> print(ast.dump(ast.parse(""" ... match x: ... case Point2D(0, 0): ... ... ... case Point3D(x=0, y=0, z=0): ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchClass( cls=Name(id='Point2D', ctx=Load()), patterns=[ MatchValue( value=Constant(value=0)), MatchValue( value=Constant(value=0))], kwd_attrs=[], kwd_patterns=[]), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchClass( cls=Name(id='Point3D', ctx=Load()), patterns=[], kwd_attrs=[ 'x', 'y', 'z'], kwd_patterns=[ MatchValue( value=Constant(value=0)), MatchValue( value=Constant(value=0)), MatchValue( value=Constant(value=0))]), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.MatchAs(pattern, name)¶
A match “as-pattern”, capture pattern or wildcard pattern.
pattern
contains the match pattern that the subject will be matched against. If the pattern isNone
, the node represents a capture pattern (i.e a bare name) and will always succeed.The
name
attribute contains the name that will be bound if the pattern is successful. Ifname
isNone
,pattern
must also beNone
and the node represents the wildcard pattern.>>> print(ast.dump(ast.parse(""" ... match x: ... case [x] as y: ... ... ... case _: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchAs( pattern=MatchSequence( patterns=[ MatchAs(name='x')]), name='y'), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchAs(), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.MatchOr(patterns)¶
A match “or-pattern”. An or-pattern matches each of its subpatterns in turn to the subject, until one succeeds. The or-pattern is then deemed to succeed. If none of the subpatterns succeed the or-pattern fails. The
patterns
attribute contains a list of match pattern nodes that will be matched against the subject.>>> print(ast.dump(ast.parse(""" ... match x: ... case [x] | (y): ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchOr( patterns=[ MatchSequence( patterns=[ MatchAs(name='x')]), MatchAs(name='y')]), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
Function and class definitions¶
- class ast.FunctionDef(name, args, body, decorator_list, returns, type_comment)¶
A function definition.
name
is a raw string of the function name.args
is anarguments
node.body
is the list of nodes inside the function.decorator_list
is the list of decorators to be applied, stored outermost first (i.e. the first in the list will be applied last).returns
is the return annotation.
- type_comment¶
type_comment
是一个可选的字符串,其中的类型注释是一个注释。
- class ast.Lambda(args, body)¶
lambda
is a minimal function definition that can be used inside an expression. UnlikeFunctionDef
,body
holds a single node.>>> print(ast.dump(ast.parse('lambda x,y: ...'), indent=4)) Module( body=[ Expr( value=Lambda( args=arguments( posonlyargs=[], args=[ arg(arg='x'), arg(arg='y')], kwonlyargs=[], kw_defaults=[], defaults=[]), body=Constant(value=Ellipsis)))], type_ignores=[])
- class ast.arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults, kwarg, defaults)¶
The arguments for a function.
posonlyargs
,args
andkwonlyargs
are lists ofarg
nodes.vararg
andkwarg
are singlearg
nodes, referring to the*args, **kwargs
parameters.kw_defaults
is a list of default values for keyword-only arguments. If one isNone
, the corresponding argument is required.defaults
is a list of default values for arguments that can be passed positionally. If there are fewer defaults, they correspond to the last n arguments.
- class ast.arg(arg, annotation, type_comment)¶
A single argument in a list.
arg
is a raw string of the argument name,annotation
is its annotation, such as aStr
orName
node.- type_comment¶
type_comment
is an optional string with the type annotation as a comment
>>> print(ast.dump(ast.parse("""\ ... @decorator1 ... @decorator2 ... def f(a: 'annotation', b=1, c=2, *d, e, f=3, **g) -> 'return annotation': ... pass ... """), indent=4)) Module( body=[ FunctionDef( name='f', args=arguments( posonlyargs=[], args=[ arg( arg='a', annotation=Constant(value='annotation')), arg(arg='b'), arg(arg='c')], vararg=arg(arg='d'), kwonlyargs=[ arg(arg='e'), arg(arg='f')], kw_defaults=[ None, Constant(value=3)], kwarg=arg(arg='g'), defaults=[ Constant(value=1), Constant(value=2)]), body=[ Pass()], decorator_list=[ Name(id='decorator1', ctx=Load()), Name(id='decorator2', ctx=Load())], returns=Constant(value='return annotation'))], type_ignores=[])
- class ast.Return(value)¶
A
return
statement.>>> print(ast.dump(ast.parse('return 4'), indent=4)) Module( body=[ Return( value=Constant(value=4))], type_ignores=[])
- class ast.Yield(value)¶
- class ast.YieldFrom(value)¶
A
yield
oryield from
expression. Because these are expressions, they must be wrapped in aExpr
node if the value sent back is not used.>>> print(ast.dump(ast.parse('yield x'), indent=4)) Module( body=[ Expr( value=Yield( value=Name(id='x', ctx=Load())))], type_ignores=[]) >>> print(ast.dump(ast.parse('yield from x'), indent=4)) Module( body=[ Expr( value=YieldFrom( value=Name(id='x', ctx=Load())))], type_ignores=[])
- class ast.Global(names)¶
- class ast.Nonlocal(names)¶
global
andnonlocal
statements.names
is a list of raw strings.>>> print(ast.dump(ast.parse('global x,y,z'), indent=4)) Module( body=[ Global( names=[ 'x', 'y', 'z'])], type_ignores=[]) >>> print(ast.dump(ast.parse('nonlocal x,y,z'), indent=4)) Module( body=[ Nonlocal( names=[ 'x', 'y', 'z'])], type_ignores=[])
- class ast.ClassDef(name, bases, keywords, starargs, kwargs, body, decorator_list)¶
A class definition.
name
is a raw string for the class namebases
is a list of nodes for explicitly specified base classes.keywords
is a list ofkeyword
nodes, principally for ‘metaclass’. Other keywords will be passed to the metaclass, as per PEP-3115.starargs
andkwargs
are each a single node, as in a function call. starargs will be expanded to join the list of base classes, and kwargs will be passed to the metaclass.body
is a list of nodes representing the code within the class definition.decorator_list
is a list of nodes, as inFunctionDef
.
>>> print(ast.dump(ast.parse("""\ ... @decorator1 ... @decorator2 ... class Foo(base1, base2, metaclass=meta): ... pass ... """), indent=4)) Module( body=[ ClassDef( name='Foo', bases=[ Name(id='base1', ctx=Load()), Name(id='base2', ctx=Load())], keywords=[ keyword( arg='metaclass', value=Name(id='meta', ctx=Load()))], body=[ Pass()], decorator_list=[ Name(id='decorator1', ctx=Load()), Name(id='decorator2', ctx=Load())])], type_ignores=[])
Async and await¶
- class ast.AsyncFunctionDef(name, args, body, decorator_list, returns, type_comment)¶
An
async def
function definition. Has the same fields asFunctionDef
.
- class ast.Await(value)¶
An
await
expression.value
is what it waits for. Only valid in the body of anAsyncFunctionDef
.
>>> print(ast.dump(ast.parse("""\
... async def f():
... await other_func()
... """), indent=4))
Module(
body=[
AsyncFunctionDef(
name='f',
args=arguments(
posonlyargs=[],
args=[],
kwonlyargs=[],
kw_defaults=[],
defaults=[]),
body=[
Expr(
value=Await(
value=Call(
func=Name(id='other_func', ctx=Load()),
args=[],
keywords=[])))],
decorator_list=[])],
type_ignores=[])
- class ast.AsyncFor(target, iter, body, orelse, type_comment)¶
- class ast.AsyncWith(items, body, type_comment)¶
async for
loops andasync with
context managers. They have the same fields asFor
andWith
, respectively. Only valid in the body of anAsyncFunctionDef
.
备注
When a string is parsed by ast.parse()
, operator nodes (subclasses
of ast.operator
, ast.unaryop
, ast.cmpop
,
ast.boolop
and ast.expr_context
) on the returned tree
will be singletons. Changes to one will be reflected in all other
occurrences of the same value (e.g. ast.Add
).
ast
中的辅助工具¶
除了节点类, ast
模块里为遍历抽象语法树定义了这些工具函数和类:
- ast.parse(source, filename='<unknown>', mode='exec', *, type_comments=False, feature_version=None)¶
把 source 解析为 AST 节点。和
compile(source, filename, mode,ast.PyCF_ONLY_AST)
等价。如果给定
type_comments=True
,解析器会被修改,以检查并返回 PEP 484 和 PEP 526 所指定的类型注释。这相当于将ast.PyCF_TYPE_COMMENTS
添加到传递给compile()
的标志中。这将报告错误的类型注释的语法错误。如果没有这个标志,类型注释将被忽略,选定的 AST 节点上的type_comment
字段将一直是None
。此外,# type: ignore
注释的位置将作为Module
的type_ignores
属性返回(否则它总是一个空列表)。此外,如果
mode
是'func_type'
,输入语法将被修改为对应于 PEP 484 签名类型注释,例如(str, int) -> List[str]
。另外,将
feature_version
设置为一个元组(major, minor)
将尝试使用该 Python 版本的语法进行解析。目前major
必须等于3
。例如,设置feature_version=(3, 4)
将允许使用async
和await
作为变量名。支持的最低版本是(3, 4)
;最高版本是sys.version_info[0:2]
。如果 source 包含一个空字符(’0’),
ValueError
将被触发。警告
注意,成功地将源代码解析成 AST 对象并不保证所提供的源代码是可以执行的有效 Python 代码,因为编译步骤可能会引发进一步的
SyntaxError
异常。例如,源码return 42
为返回语句生成了一个有效的 AST 节点,但它不能被单独编译(它需要在一个函数节点内)。特别是,
ast.parse()
不会做任何范围检查,而编译步骤会做。警告
足够复杂或是巨大的字符串可能导致 Python 解释器的崩溃,因为 Python 的 AST 编译器是有栈深限制的。
在 3.8 版更改: 增加了
type_comments
、mode='func_type'
和feature_version
。
- ast.unparse(ast_obj)¶
反向解析
ast.AST
对象,并生成一个字符串,如果用ast.parse()
解析,将产生一个等价的ast.AST
对象的代码。警告
产生的代码字符串不一定等于产生
ast.AST
对象的原始代码(没有任何编译器优化,如常数 tuple/frozenset)。警告
试图解读一个高度复杂的表达式会导致
RecursionError
。3.9 新版功能.
- ast.literal_eval(node_or_string)¶
Evaluate an expression node or a string containing only a Python literal or container display. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans,
None
andEllipsis
.This can be used for evaluating strings containing Python values without the need to parse the values oneself. It is not capable of evaluating arbitrarily complex expressions, for example involving operators or indexing.
This function had been documented as “safe” in the past without defining what that meant. That was misleading. This is specifically designed not to execute Python code, unlike the more general
eval()
. There is no namespace, no name lookups, or ability to call out. But it is not free from attack: A relatively small input can lead to memory exhaustion or to C stack exhaustion, crashing the process. There is also the possibility for excessive CPU consumption denial of service on some inputs. Calling it on untrusted data is thus not recommended.警告
It is possible to crash the Python interpreter due to stack depth limitations in Python’s AST compiler.
它可能引发
ValueError
,TypeError
,SyntaxError
,MemoryError
和RecursionError
,取决于错误的输入。在 3.2 版更改: 目前支持字节和集合。
在 3.9 版更改: 现在支持用
'set()'
创建空集合。在 3.10 版更改: 对于字符串输入,前面的空格和制表符现在被剥离了。
- ast.get_docstring(node, clean=True)¶
返回给定 node 的文档字符串(必须是
FunctionDef
、AsyncFunctionDef
、ClassDef
或Module
节点),如果没有文档字符串,则返回None
。如果 clean 为真,则用inspect.cleandoc()
清理该文档字符串的缩进。在 3.5 版更改: 目前支持
AsyncFunctionDef
。
- ast.get_source_segment(source, node, *, padded=False)¶
获取生成 node 的 source 的源代码段。如果某些位置信息(
lineno
、end_lineno
、col_offset
或end_col_offset
)丢失,返回None
。如果 padded 是
True
,多行语句的第一行将被填充空格,以符合其原始位置。3.8 新版功能.
- ast.fix_missing_locations(node)¶
当你用
compile()
编译一个节点树时,编译器期望lineno
和col_offset
的属性对每一个节点均支持。这对于生成的节点来说是相当繁琐的,所以这个帮助器在没有设置的地方递归地添加这些属性,将它们设置为父节点的值。它从 node 开始递归工作。
- ast.increment_lineno(node, n=1)¶
将树中从 node 开始的每个节点的行号和末行号增加 n。这对 “移动代码” 到文件中的不同位置很有用。
- ast.copy_location(new_node, old_node)¶
如果可能的话,从 old_node 复制源位置(
lineno
、col_offset
、end_lineno
和end_col_offset
)到 new_node,并返回 new_node。
- ast.iter_fields(node)¶
为 node 上存在的
node._fields
中的每个字段产生一个(fieldname, value)
的元组。
- ast.iter_child_nodes(node)¶
产生 node 的所有直接子节点,即所有属于节点的字段和属于节点列表的字段的所有项目。
- ast.walk(node)¶
递归产生树中从 node 开始的所有后代节点(包括 node 本身),没有指定顺序。如果你只想就地修改节点,而不关心上下文,这很有用。
- class ast.NodeVisitor¶
一个节点访问者基类,它行走在抽象的语法树上,为每个发现的节点调用一个访问者函数。这个函数可以返回一个值,由
visit()
方法转发。这个类是要被子类化的,子类会增加访问者方法。
- visit(node)¶
访问一个节点。默认实现是调用
self.visit_classname
的方法,其中 classname 是节点类的名称,如果该方法不存在,则调用generic_visit()
。
- generic_visit(node)¶
这个访问者在节点的所有子节点上调用
visit()
。注意,拥有自定义访客方法的节点的子节点不会被访问,除非访客调用
generic_visit()
或自己访问它们。
如果你想在遍历过程中对节点进行修改,请不要使用
NodeVisitor
。为此,存在一个特殊的访问者(NodeTransformer
),允许修改。3.8 版后已移除: 方法
visit_Num()
、visit_Str()
、visit_Bytes()
、visit_NameConstant()
和visit_Ellipsis()
现在已经废弃,在未来的 Python 版本中不会被调用。添加visit_Constant()
方法来处理所有常数节点。
- class ast.NodeTransformer¶
子类
NodeVisitor
用于遍历抽象语法树,并允许修改节点。NodeTransformer
将遍历抽象语法树并使用visitor方法的返回值去替换或移除旧节点。如果visitor方法的返回值为None
, 则该节点将从其位置移除,否则将替换为返回值。当返回值是原始节点时,无需替换。如下是一个转换器示例,它将所有出现的名称 (
foo
) 重写为data['foo']
:class RewriteName(NodeTransformer): def visit_Name(self, node): return Subscript( value=Name(id='data', ctx=Load()), slice=Constant(value=node.id), ctx=node.ctx )
请记住,如果您正在操作的节点具有子节点,则必须先转换其子节点或为该节点调用
generic_visit()
方法。对于属于语句集合(适用于所有语句节点)的节点,访问者还可以返回节点列表而不仅仅是单个节点。
如果
NodeTransformer
引入了新的节点(不是原来树的一部分),而没有给它们位置信息(比如lineno
),那么fix_missing_locations()
应该与新的子树一起调用,以重新计算位置信息tree = ast.parse('foo', mode='eval') new_tree = fix_missing_locations(RewriteName().visit(tree))
通常你可以像这样使用转换器
node = YourTransformer().visit(node)
- ast.dump(node, annotate_fields=True, include_attributes=False, *, indent=None)¶
返回 node 中树的格式化转储。这主要是为了调试的目的。如果 annotate_fields 为 true(默认),返回的字符串将显示字段的名称和值。如果 annotate_fields 为 false,结果字符串将通过省略不明确的字段名而变得更加紧凑。默认情况下,诸如行号和列的偏移量等属性不会被转储。如果希望这样,可以将 include_attributes 设置为 true。
如果 indent 是一个非负的整数或字符串,那么树就会以该缩进级别进行漂亮的打印。缩进级别为 0、负数或
""
将只插入新行。None
(默认)选择单行表示法。使用正的整数缩进,每一级有那么多的空格。如果 indent 是一个字符串(如"\t"
),该字符串将用于缩进每一级。在 3.9 版更改: 添加 indent 选项。
Compiler Flags¶
The following flags may be passed to compile()
in order to change
effects on the compilation of a program:
- ast.PyCF_ALLOW_TOP_LEVEL_AWAIT¶
Enables support for top-level
await
,async for
,async with
and async comprehensions.3.8 新版功能.
- ast.PyCF_ONLY_AST¶
Generates and returns an abstract syntax tree instead of returning a compiled code object.
命令行用法¶
3.9 新版功能.
The ast
module can be executed as a script from the command line.
It is as simple as:
python -m ast [-m <mode>] [-a] [infile]
可以接受以下选项:
- -h, --help¶
Show the help message and exit.
- -m <mode>¶
- --mode <mode>¶
Specify what kind of code must be compiled, like the mode argument in
parse()
.
- --no-type-comments¶
Don’t parse type comments.
- -a, --include-attributes¶
Include attributes such as line numbers and column offsets.
If infile
is specified its contents are parsed to AST and dumped
to stdout. Otherwise, the content is read from stdin.
参见
Green Tree Snakes, an external documentation resource, has good details on working with Python ASTs.
ASTTokens annotates Python ASTs with the positions of tokens and text in the source code that generated them. This is helpful for tools that make source code transformations.
leoAst.py unifies the token-based and parse-tree-based views of python programs by inserting two-way links between tokens and ast nodes.
LibCST parses code as a Concrete Syntax Tree that looks like an ast tree and keeps all formatting details. It’s useful for building automated refactoring (codemod) applications and linters.
Parso is a Python parser that supports error recovery and round-trip parsing for different Python versions (in multiple Python versions). Parso is also able to list multiple syntax errors in your python file.