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)
| 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 -
Это базовый класс для всех классов узлов AST. Фактические классы узлов получены из файла
Parser/Python.asdl, который воспроизведён выше. Они определены в модуле C_astи повторно экспортируются в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.Module(body, type_ignores) -
Модуль Python, как и при вводе из файла. Тип узла, создаваемый функцией
ast.parse()в режиме"exec"по умолчанию.body — это
listинструкций модуля.type_ignores — это
listкомментариев модуля с указанием игнорировать тип; подробнее см.ast.parse().>>> print(ast.dump(ast.parse('x = 1'), indent=4)) Module( body=[ Assign( targets=[ Name(id='x', ctx=Store())], value=Constant(value=1))], type_ignores=[])
-
class ast.Expression(body) -
Отдельное выражение, переданное на вход Python. Тип узла, создаваемый функцией
ast.parse(), если mode равен"eval".body — это отдельный узел, один из типов выражений.
>>> print(ast.dump(ast.parse('123', mode='eval'), indent=4)) Expression( body=Constant(value=123))
-
class ast.Interactive(body) -
Отдельный фрагмент интерактивного ввода, как в интерактивном режиме. Тип узла, создаваемый функцией
ast.parse(), если mode равен"single".body — это
listузлов инструкций.>>> print(ast.dump(ast.parse('x = 1; y = 2', mode='single'), indent=4)) Interactive( body=[ Assign( targets=[ Name(id='x', ctx=Store())], value=Constant(value=1)), Assign( targets=[ Name(id='y', ctx=Store())], value=Constant(value=2))])
-
class ast.FunctionType(argtypes, returns) -
Представление комментариев типов старого формата для функций, поскольку в версиях Python до 3.5 не поддерживались аннотации PEP 484. Тип узла, создаваемый функцией
ast.parse(), если mode равен"func_type".Такие комментарии типов выглядят следующим образом:
def sum_two_number(a, b): # type: (int, int) -> int return a + bargtypes — это
listузлов выражений.returns — это отдельный узел выражения.
>>> print(ast.dump(ast.parse('(int, str) -> List[int]', mode='func_type'), indent=4)) FunctionType( argtypes=[ Name(id='int', ctx=Load()), Name(id='str', ctx=Load())], returns=Subscript( value=Name(id='List', ctx=Load()), slice=Name(id='int', ctx=Load()), ctx=Load()))Добавлено в версии 3.8.
Литералы
-
class ast.Constant(value) -
Постоянное значение. Атрибут
valueлитералаConstantсодержит представленный им объект Python. Представленные значения могут быть простыми типами, такими как число, строка илиNone, а также неизменяемыми контейнерами (кортежами и frozenset), если все их элементы являются константами.>>> 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: форматирование repr
!r - 97: форматирование ascii
!a
-
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, а в соответствующей позиции списка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. Этот тип необходимо использовать при создании узла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) -
Вызов функции.
func— это функция, которой часто является объектNameилиAttribute. Аргументы:-
argsсодержит список позиционных аргументов. -
keywordsсодержит список объектовkeyword, представляющих именованные аргументы.
При создании узла
Callобязательныargsиkeywords, но они могут быть пустыми списками.>>> 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). Может встречаться только в поле 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.TryStar(body, handlers, orelse, finalbody) -
Блоки
try, за которыми следуют частиexcept*. Атрибуты те же, что и уTry, но узлыExceptHandlerвhandlersрассматриваются как блокиexcept*, а не какexcept.>>> 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— исходная строка имени, которому будет присвоено исключение, либо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) -
Один вариант с образцом в операторе
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— узел выражения. Допустимые узлы-значения ограничены, как описано в документации к оператору сопоставления с образцом. Этот образец считается успешным, если объект сопоставления равен вычисленному значению.>>> 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, словарь с оставшимися элементами отображения связывается с этим именем, если образец отображения в целом успешен.>>> 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, чтобы сопоставлять узел образца с проверяемым экземпляром. Некоторые встроенные типы сопоставляются таким же образом, как описано в документации к оператору сопоставления с образцом.
>>> 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) -
Образец сопоставления «as», образец захвата или образец-шаблон.
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) -
Образец сопоставления «или». Образец «или» последовательно сопоставляет с объектом каждый из вложенных образцов, пока один из них не сработает. После этого образец «или» считается успешным. Если ни один из вложенных образцов не сработал, образец «или» считается неуспешным. Атрибут
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— его аннотация, например узел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, body, decorator_list) -
Определение класса.
-
name— исходная строка с именем класса -
bases— список узлов для явно указанных базовых классов. -
keywords— список узловkeyword, в основном для ‘metaclass’. Другие именованные аргументы будут переданы метаклассу согласно PEP-3115. -
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=[]) -
Асинхронное выполнение и await
-
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. Например, установкаfeature_version=(3, 9)позволит попытаться запретить разбор операторовmatch. В настоящее времяmajorдолжно быть равно3. Наименьшая поддерживаемая версия —(3, 4)(в будущих версиях Python это значение может увеличиться); наибольшая —sys.version_info[0:2]. Под попыткой «по возможности» подразумевается, что нет гарантии, что результат разбора (или его успешность) будет таким же, как при запуске в версии Python, соответствующейfeature_version.Если исходный код содержит нулевой символ (
\0), возникает исключениеValueError.Предупреждение
Обратите внимание: успешный разбор исходного кода в объект AST не гарантирует, что предоставленный исходный код является допустимым кодом Python, который можно выполнить, поскольку на этапе компиляции могут возникнуть дополнительные исключения
SyntaxError. Например, исходный кодreturn 42создает допустимый узел AST для оператора return, но сам по себе не может быть скомпилирован (он должен находиться внутри узла функции).В частности,
ast.parse()не выполняет проверку областей видимости, которая проводится на этапе компиляции.Предупреждение
Из-за ограничений глубины стека в компиляторе AST Python достаточно большая или сложная строка может привести к аварийному завершению интерпретатора Python.
Изменено в версии 3.8: Добавлены
type_comments,mode='func_type'иfeature_version.
-
ast.unparse(ast_obj) -
Преобразует объект
ast.ASTобратно в исходный код и создает строку с кодом, который при повторном разборе с помощьюast.parse()создал бы эквивалентный объектast.AST.Предупреждение
Созданная строка кода не обязательно будет совпадать с исходным кодом, из которого был получен объект
ast.AST(если не учитывать оптимизации компилятора, например кортежи или неизменяемые множества-константы).Предупреждение
Попытка преобразовать обратно в исходный код очень сложное выражение приведет к исключению
RecursionError.Добавлено в версии 3.9.
-
ast.literal_eval(node_or_string) -
Вычисляет узел-выражение или строку, содержащую только литерал Python или запись контейнера. Предоставленная строка или узел могут состоять только из следующих литеральных конструкций Python: строки, байты, числа, кортежи, списки, словари, множества, логические значения,
NoneиEllipsis.Эту функцию можно использовать для вычисления строк, содержащих значения Python, без необходимости самостоятельно разбирать эти значения. Она не умеет вычислять произвольно сложные выражения, например с операторами или индексацией.
Ранее эта функция описывалась как «безопасная», но без объяснения значения этого термина. Это вводило в заблуждение. Функция специально разработана так, чтобы не выполнять код Python, в отличие от более универсальной функции
eval(). У нее нет пространства имен, поиска имен или возможности вызывать внешние функции. Однако она не защищена от атак: относительно небольшой объем входных данных может привести к исчерпанию памяти или стека C и аварийному завершению процесса. Некоторые входные данные также могут вызвать чрезмерную нагрузку на процессор и отказ в обслуживании. Поэтому не рекомендуется вызывать эту функцию для недоверенных данных.Предупреждение
Из-за ограничений глубины стека в компиляторе AST Python интерпретатор Python может аварийно завершиться.
В зависимости от некорректных входных данных могут возникнуть исключения
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 имеет значение true, функция очищает отступы в строке документации с помощьюinspect.cleandoc().Изменено в версии 3.5: Теперь поддерживается
AsyncFunctionDef.
-
ast.get_source_segment(source, node, *, padded=False) -
Возвращает сегмент исходного кода source, из которого был создан узел node. Если отсутствует какая-либо информация о расположении (
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) -
Для каждого поля из
node._fields, имеющегося у узла node, выдает кортеж(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()или не посетит их самостоятельно.
-
visit_Constant(node) -
Обрабатывает все узлы-константы.
Не используйте
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 -
Включить такие атрибуты, как номера строк и смещения столбцов.
-
-i <indent> -
--indent <indent> -
Отступы узлов AST (количество пробелов).
Если задан infile, его содержимое разбирается в AST, а результат выводится в stdout. В противном случае содержимое считывается из stdin.
См. также
Green Tree Snakes, внешний ресурс документации, содержит полезные подробные сведения о работе с AST Python.
ASTTokens дополняет AST Python сведениями о расположении токенов и текста в исходном коде, из которого они были созданы. Это полезно для инструментов преобразования исходного кода.
leoAst.py объединяет представления программ Python на основе токенов и дерева разбора, создавая двусторонние связи между токенами и узлами AST.
LibCST разбирает код в конкретное синтаксическое дерево, похожее на дерево AST и сохраняющее все детали форматирования. Оно полезно для создания приложений автоматического рефакторинга (codemod) и линтеров.
Parso — парсер Python с поддержкой восстановления после ошибок и разбора с обратным преобразованием для разных версий Python (в нескольких версиях Python). Parso также умеет находить несколько синтаксических ошибок в файле Python.
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/ast.html