ast
— Абстрактные синтаксические деревья¶
Исходный код: Lib/ast.py.
Модуль ast
помогает приложениям Python обрабатывать деревья грамматики абстрактного синтаксиса Python. Сам абстрактный синтаксис может меняться с каждым выпуском Python; этот модуль помогает программно узнать, как выглядит текущая грамматика.
Абстрактное синтаксическое дерево может быть сгенерировано путем передачи ast.PyCF_ONLY_AST
в качестве флага встроенной функции compile()
или с помощью помощника parse()
, предоставленного в этом модуле. Результатом будет дерево объектов, все классы которых наследуются от ast.AST
. Абстрактное синтаксическое дерево может быть скомпилировано в объект кода Python с помощью встроенной функции compile()
.
Абстрактная грамматика¶
В настоящее время абстрактная грамматика определяется следующим образом:
-- 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)
| 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
¶ Это основа всех классов узлов AST. Фактические классы узлов являются производными от файла
Parser/Python.asdl
, который воспроизводится above. Они определены в модуле_ast
на языке C и реэкспортированы вast
.Для каждого символа левой стороны в абстрактной грамматике определен один класс (например,
ast.stmt
илиast.expr
). Кроме того, для каждого конструктора правой стороны определен один класс; эти классы наследуются от классов для деревьев левой стороны. Например,ast.BinOp
наследуется отast.expr
. Для производственных правил с альтернативами (они же «суммы») класс левой стороны является абстрактным: создаются только экземпляры конкретных узлов конструктора.-
_fields
¶ Каждый конкретный класс имеет атрибут
_fields
, который дает имена всех дочерних узлов.Каждый экземпляр конкретного класса имеет один атрибут для каждого дочернего узла, тип которого определен в грамматике. Например, экземпляры
ast.BinOp
имеют атрибутleft
типаast.expr
.Если эти атрибуты помечены в грамматике как необязательные (с помощью знака вопроса), то значение может быть
None
. Если атрибуты могут иметь ноль или более значений (помечены звездочкой), то значения представляются в виде списков Python. Все возможные атрибуты должны присутствовать и иметь допустимые значения при компиляции AST с помощьюcompile()
.
-
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. Тем временем их инстанцирование будет возвращать экземпляр другого класса.
Примечание
Представленные здесь описания конкретных классов узлов были первоначально адаптированы из фантастического проекта Green Tree Snakes и всех его участников.
Литература¶
-
class
ast.
Constant
(value)¶ Постоянное значение. Атрибут
value
литералаConstant
содержит объект 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
повторное форматирование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
являетсяStore
, если контейнер является целью присваивания (т.е.(x,y)=something
), и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)¶ Булева операция, „или“ или „и“.
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
, представляющих аргументы, переданные ключевым словом.
При создании узла
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)))
Subscripting¶
-
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
). Может встречаться только внутри поля slice вSubscript
, либо непосредственно, либо как элемент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
представляют собой присвоение каждому из них одного и того же значения. Распаковка представлена помещениемTuple
илиList
внутриtargets
.-
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
- булево целое число, установленное в True для узлаName
вtarget
, которые не появляются между скобками и, следовательно, являются чистыми именами, а не выражениями.>>> 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
является узломName
дляx
(с контекстомStore
),op
являетсяAdd
, аvalue
являетсяConstant
со значением 1.Атрибут
target
не может быть классаTuple
илиList
, в отличие от целейAssign
.>>> 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
- это необязательная часть дляy
вraise x from 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=[])
Другие утверждения, которые применимы только внутри функций или циклов, описаны в других разделах.
Импорт¶
-
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 . import 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)¶ Цикл
for
.target
содержит переменную(ые), которой присваивается цикл, в виде одного узлаName
,Tuple
илиList
.iter
содержит элемент, по которому будет выполняться цикл, опять же в виде одного узла.body
иorelse
содержат списки узлов для выполнения. Узлы вorelse
выполняются, если цикл завершается нормально, а не через операторbreak
.-
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.
ExceptHandler
(type, name, body)¶ Одиночная оговорка
except
.type
- это тип исключения, которому оно будет соответствовать, обычно узелName
(илиNone
для всеобъемлющей клаузулыexcept:
).name
- необработанная строка для имени, в котором будет храниться исключение, илиNone
, если в оговорке нетas foo
.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=[])
Соответствие шаблонов¶
-
class
ast.
Match
(subject, cases)¶ Утверждение
match
.subject
содержит субъект сопоставления (объект, который сопоставляется со случаями), аcases
содержит итерацию узловmatch_case
с различными случаями.
-
class
ast.
match_case
(pattern, guard, body)¶ Одиночный шаблон case в операторе
match
.pattern
содержит шаблон соответствия, с которым будет сопоставлен объект. Обратите внимание, что узлыAST
, создаваемые для шаблонов, отличаются от узлов, создаваемых для выражений, даже если они имеют одинаковый синтаксис.Атрибут
guard
содержит выражение, которое будет оценено, если шаблон соответствует субъекту.body
содержит список узлов, которые будут выполняться, если шаблон совпадает и результат оценки защитного выражения равен 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)¶ Литерал соответствия или шаблон значения, который сравнивает по равенству.
value
является узлом выражения. Допустимые узлы значений ограничены, как описано в документации по оператору match. Шаблон успешный, если объект совпадения равен оцениваемому значению.>>> 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)¶ Буквальный шаблон совпадения, который сравнивает по идентичности.
value
- это синглтон, с которым производится сравнение:None
,True
илиFalse
. Этот шаблон успешный, если объектом сравнения является данная константа.>>> 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)¶ Шаблон последовательности сопоставления.
patterns
содержит шаблоны, которые будут сопоставлены с элементами субъекта, если субъект является последовательностью. Сопоставляет последовательность переменной длины, если один из подшаблонов является узломMatchStar
, в противном случае сопоставляет последовательность фиксированной длины.>>> 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)¶ Сопоставляет оставшуюся часть последовательности в шаблоне последовательности переменной длины. Если
name
не являетсяNone
, то при успешном выполнении общего шаблона последовательности к этому имени привязывается список, содержащий оставшиеся элементы последовательности.>>> 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)¶ Шаблон сопоставления.
keys
- это последовательность узлов выражения.patterns
- это соответствующая последовательность узлов шаблона.rest
- необязательное имя, которое может быть указано для захвата оставшихся элементов отображения. Допустимые ключевые выражения ограничены, как описано в документации по оператору соответствия.Этот шаблон успешный, если объект является отображением, все оцененные ключевые выражения присутствуют в отображении, и значение, соответствующее каждому ключу, соответствует соответствующему подшаблону. Если
rest
не являетсяNone
, то в случае успеха всего шаблона отображения к этому имени привязывается dict, содержащий остальные элементы отображения.>>> 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)¶ Шаблон класса соответствия.
cls
- выражение, задающее номинальный класс для сопоставления.patterns
- последовательность узлов шаблона для сопоставления с определенной классом последовательностью атрибутов сопоставления шаблона.kwd_attrs
- последовательность дополнительных атрибутов для сопоставления (указываются как аргументы ключевых слов в шаблоне класса),kwd_patterns
- соответствующие шаблоны (указываются как значения ключевых слов в шаблоне класса).Эта схема успешна, если субъект является экземпляром указанного класса, все позиционные шаблоны соответствуют соответствующим атрибутам, определенным классом, и любые указанные атрибуты ключевых слов соответствуют соответствующему шаблону.
Примечание: классы могут определять свойство, возвращающее self, чтобы сопоставить узел шаблона с сопоставляемым экземпляром. Некоторые встроенные типы также сопоставляются таким образом, как описано в документации по оператору match.
>>> 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)¶ Соответствие «как шаблон», шаблон захвата или шаблон подстановочного знака.
pattern
содержит шаблон соответствия, по которому будет сопоставлен объект. Если шаблонNone
, узел представляет собой шаблон захвата (т.е. голое имя) и всегда будет успешным.Атрибут
name
содержит имя, которое будет связано в случае успеха шаблона. Еслиname
являетсяNone
,pattern
также должен бытьNone
, а узел представляет собой шаблон подстановочного знака.>>> 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)¶ Соответствие «или-шаблон». Шаблон «или» поочередно сопоставляет каждый из своих подшаблонов с объектом, пока один из них не окажется успешным. После этого считается, что шаблон «или» достиг успеха. Если ни один из подшаблонов не достиг успеха, то or-шаблон не работает. Атрибут
patterns
содержит список узлов шаблона соответствия, которые будут сопоставлены с объектом.>>> 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=[])
Определения функций и классов¶
-
class
ast.
FunctionDef
(name, args, body, decorator_list, returns, type_comment)¶ Определение функции.
name
- необработанная строка имени функции.args
является узломarguments
.body
- это список узлов внутри функции.decorator_list
- это список декораторов, которые будут применены, хранятся сначала крайние (т.е. первый в списке будет применен последним).returns
- это аннотация возврата.
-
type_comment
¶ type_comment
- необязательная строка с аннотацией типа в качестве комментария.
-
class
ast.
Lambda
(args, body)¶ lambda
- это минимальное определение функции, которое может быть использовано внутри выражения. В отличие отFunctionDef
,body
содержит один узел.>>> 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)¶ Аргументы для функции.
posonlyargs
,args
иkwonlyargs
являются списками узловarg
.vararg
иkwarg
являются одиночными узламиarg
, ссылающимися на параметры*args, **kwargs
.kw_defaults
- это список значений по умолчанию для аргументов, относящихся только к ключевым словам. Если одно из нихNone
, то соответствующий аргумент является обязательным.defaults
- это список значений по умолчанию для аргументов, которые могут быть переданы позиционно. Если значений по умолчанию меньше, они соответствуют последним n аргументам.
-
class
ast.
arg
(arg, annotation, type_comment)¶ Одиночный аргумент в списке.
arg
- необработанная строка имени аргумента,annotation
- его аннотация, например, узелStr
илиName
.-
type_comment
¶ type_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)¶ Оператор
return
.>>> 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)¶ Выражение
yield
илиyield from
. Поскольку это выражения, они должны быть обернуты в узелExpr
, если отправленное обратно значение не используется.>>> 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
иnonlocal
утверждения.names
представляет собой список необработанных строк.>>> 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)¶ Определение класса.
name
- необработанная строка для имени классаbases
- это список узлов для явно указанных базовых классов.keywords
представляет собой список узловkeyword
, в основном для „metaclass“. Другие ключевые слова будут переданы в метакласс в соответствии с PEP-3115.starargs
иkwargs
- это каждый отдельный узел, как в вызове функции. starargs будет расширен для присоединения к списку базовых классов, а kwargs будет передан метаклассу.body
- это список узлов, представляющих код внутри определения класса.decorator_list
- это список узлов, как вFunctionDef
.
>>> 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=[])
Асинхронность и ожидание¶
-
class
ast.
AsyncFunctionDef
(name, args, body, decorator_list, returns, type_comment)¶ Определение функции
async def
. Имеет те же поля, что иFunctionDef
.
-
class
ast.
Await
(value)¶ Выражение
await
.value
- это то, чего оно ожидает. Действителен только в теле выраженияAsyncFunctionDef
.
>>> 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
циклы иasync with
контекстные менеджеры. Они имеют те же поля, что иFor
иWith
соответственно. Действительны только в телеAsyncFunctionDef
.
Примечание
Когда строка разбирается с помощью ast.parse()
, операторные узлы (подклассы ast.operator
, ast.unaryop
, ast.cmpop
, ast.boolop
и ast.expr_context
) на возвращаемом дереве будут синглтонами. Изменения в одном из них будут отражены во всех остальных вхождениях того же значения (например, ast.Add
).
ast
Помощники¶
Помимо классов узлов, модуль ast
определяет эти служебные функции и классы для обхода абстрактных синтаксических деревьев:
-
ast.
parse
(source, filename='<unknown>', mode='exec', *, type_comments=False, feature_version=None)¶ Разобрать источник в узел AST. Эквивалентно
compile(source, filename, mode, ast.PyCF_ONLY_AST)
.Если указано
type_comments=True
, синтаксический анализатор модифицируется для проверки и возврата комментариев типов, указанных PEP 484 и PEP 526. Это эквивалентно добавлениюast.PyCF_TYPE_COMMENTS
к флагам, переданным вcompile()
. Это сообщит о синтаксических ошибках для неправильно размещенных комментариев типов. Без этого флага комментарии типов будут игнорироваться, а полеtype_comment
в выбранных узлах AST всегда будетNone
. Кроме того, расположение комментариев# type: ignore
будет возвращаться в виде атрибутаtype_ignores
вModule
(иначе это всегда пустой список).Кроме того, если
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]
.Если источник содержит нулевой символ (“0“), выдается сообщение
ValueError
.Предупреждение
Обратите внимание, что успешный разбор исходного кода в объект AST не гарантирует, что предоставленный исходный код является корректным кодом Python, который может быть выполнен, так как на этапе компиляции могут возникнуть дополнительные исключения
SyntaxError
. Например, источникreturn 42
генерирует корректный узел AST для оператора return, но он не может быть скомпилирован сам по себе (он должен находиться внутри узла функции).В частности,
ast.parse()
не будет выполнять никаких проверок масштабирования, что делает шаг компиляции.Предупреждение
Возможно аварийное завершение работы интерпретатора Python с достаточно большой/сложной строкой из-за ограничений глубины стека в AST-компиляторе Python.
Изменено в версии 3.8: Добавлены
type_comments
,mode='func_type'
иfeature_version
.
-
ast.
unparse
(ast_obj)¶ Разберите объект
ast.AST
и сгенерируйте строку с кодом, который произведет эквивалентный объектast.AST
, если его разобрать обратно с помощьюast.parse()
.Предупреждение
Произведенная строка кода не обязательно будет равна исходному коду, который сгенерировал объект
ast.AST
(без каких-либо оптимизаций компилятора, таких как константные кортежи/розетки).Предупреждение
Попытка разобрать очень сложное выражение приведет к результату
RecursionError
.Добавлено в версии 3.9.
-
ast.
literal_eval
(node_or_string)¶ Безопасная оценка узла выражения или строки, содержащей литерал Python или контейнерное отображение. Предоставленная строка или узел могут состоять только из следующих буквенных структур Python: строки, байты, числа, кортежи, списки, dicts, множества, булевы,
None
иEllipsis
.Это можно использовать для безопасной оценки строк, содержащих значения Python из ненадежных источников без необходимости самостоятельно разбирать значения. Он не способен оценивать произвольно сложные выражения, например, с операторами или индексацией.
Предупреждение
Возможно аварийное завершение работы интерпретатора Python с достаточно большой/сложной строкой из-за ограничений глубины стека в AST-компиляторе Python.
В зависимости от искаженного ввода он может вызвать
ValueError
,TypeError
,SyntaxError
,MemoryError
иRecursionError
.Изменено в версии 3.2: Теперь позволяет использовать байты и литералы множеств.
Изменено в версии 3.9: Теперь поддерживается создание пустых множеств с помощью
'set()'
.Изменено в версии 3.10: При вводе строк ведущие пробелы и табуляции теперь удаляются.
-
ast.
get_docstring
(node, clean=True)¶ Возвращает docstring данного node (который должен быть узлом
FunctionDef
,AsyncFunctionDef
,ClassDef
илиModule
), илиNone
, если он не имеет docstring. Если clean равно true, очистите отступы doc-строки с помощьюinspect.cleandoc()
.Изменено в версии 3.5:
AsyncFunctionDef
теперь поддерживается.
-
ast.
get_source_segment
(source, node, *, padded=False)¶ Получить сегмент исходного кода источника, который породил узел. Если некоторая информация о местоположении (
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)¶ Скопируйте местоположение источника (
lineno
,col_offset
,end_lineno
иend_col_offset
) из old_node в new_node, если это возможно, и верните new_node.
-
ast.
iter_fields
(node)¶ Выдает кортеж
(fieldname, value)
для каждого поля вnode._fields
, которое присутствует на узле.
-
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
пройдет по AST и использует возвращаемое значение методов посетителей для замены или удаления старого узла. Если возвращаемое значение метода посетителя равно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.
Флаги компилятора¶
Следующие флаги могут быть переданы в compile()
для изменения влияния на компиляцию программы:
-
ast.
PyCF_ALLOW_TOP_LEVEL_AWAIT
¶ Включает поддержку верхнего уровня
await
,async for
,async with
и асинхронных пониманий.Добавлено в версии 3.8.
-
ast.
PyCF_ONLY_AST
¶ Генерирует и возвращает абстрактное дерево синтаксиса вместо того, чтобы возвращать объект скомпилированного кода.
Использование командной строки¶
Добавлено в версии 3.9.
Модуль ast
может быть выполнен как сценарий из командной строки. Это очень просто:
python -m ast [-m <mode>] [-a] [infile]
Принимаются следующие варианты:
-
-h
,
--help
¶
Покажите сообщение справки и выйдите.
-
-m
<mode>
¶ -
--mode
<mode>
¶ Укажите, какой тип кода должен быть скомпилирован, подобно аргументу mode в
parse()
.
-
--no-type-comments
¶
Не разбирайте комментарии типа.
-
-a
,
--include-attributes
¶
Включите такие атрибуты, как номера строк и смещения колонок.
Если указано infile
, его содержимое разбирается на AST и выводится на stdout. В противном случае содержимое считывается из stdin.
См.также
Green Tree Snakes, внешний ресурс документации, содержит хорошие подробности о работе с АСТ Python.
ASTTokens аннотирует АСТ Python с указанием позиций лексем и текста в исходном коде, который их породил. Это полезно для инструментов, которые выполняют преобразования исходного кода.
leoAst.py объединяет представления программ на основе лексем и деревьев разбора python, вставляя двусторонние связи между лексемами и узлами ast.
LibCST разбирает код в виде конкретного синтаксического дерева, которое выглядит как дерево ast и сохраняет все детали форматирования. Это полезно для создания приложений автоматического рефакторинга (codemod) и линтеров.
Parso - это парсер Python, который поддерживает восстановление ошибок и парсинг по кругу для различных версий Python (в нескольких версиях Python). Parso также способен перечислить множество синтаксических ошибок в вашем файле python.