源代码: Lib/ast.py
创新互联建站是专业的淄博网站建设公司,淄博接单;提供成都网站设计、网站建设,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行淄博网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
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 in ast.
抽象语法定义的每个左侧符号(比方说, 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_lineno 属性。lineno 和 end_lineno 是源代码的第一行行数和最后一行行数(从1开始, 所以第一行行数是1),而 col_offset 和 end_col_offset 是该生成节点第一个和最后一个 token 的 UTF-8 字节偏移量。记录下 UTF-8 偏移量的原因是 parser 内部使用 UTF-8 。
注意编译器不需要结束位置,所以结束位置是可选的。结束偏移在最后一个符号*之后*,例如你可以通过 source_line[node.col_offset : node.end_col_offset]
获得一个单行表达式节点的源码片段。
一个类的构造器 ast.T
像下面这样parse它的参数。
如果有位置参数,它们必须和 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 版本中被移除。同时,实例化它们会返回一个不同类的实例。
备注
在此显示的特定节点类的描述最初是改编自杰出的 Green Tree Snakes 项目及其所有贡献者。
class ast.Constant(value)
一个常量。 Constant
字面值的 value
属性即为其代表的 Python 对象。它可以代表简单的数字,字符串或者 None
对象,但是也可以代表所有元素都是常量的不可变容器(例如元组或冻结集合)。
>>> print(ast.dump(ast.parse('123', mode='eval'), indent=4))
Expression(
body=Constant(value=123))
class ast.FormattedValue(value, conversion, format_spec)
节点是以一个 f-字符串形式的格式化字段来代表的。 如果该字符串只包含单个格式化字段而没有任何其他内容则节点可以被隔离,否则它将在 JoinedStr 中出现。
value
为任意的表达式节点(如一个字面值、变量或函数调用)。
conversion
是一个整数:
-1: 无格式化
115: !s
字符串格式化
114: !r
repr 格式化
97: !a
ascii 格式化
format_spec
是一个代表值的格式化的 JoinedStr 节点,或者如果未指定格式则为 None
。 conversion
和 format_spec
可以被同时设置。
class ast.JoinedStr(values)
一个 f-字符串,由一系列 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
保存一个代表元素的节点的列表。 ctx
在容器为赋值的目标时 (如 (x,y)=something
) 是 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
列表,并将 None
放入 keys
的对应位置。
>>> 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 节点。 此类型必须在构建 Call 节点并传入 *args
时被使用。
>>> 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.And
class ast.Or
布尔运算符对应的形符。
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 对象的列表。
当创建一个 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
是索引号、切片或键。 它可以是一个包含 Slice 的 Tuple。 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 名称栏目:创新互联Python教程:ast —- 抽象语法树
网站URL:http://www.mswzjz.cn/qtweb/news22/44072.html攀枝花网站建设、攀枝花网站运维推广公司-贝锐智能,是专注品牌与效果的网络营销公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 贝锐智能