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, type_param* type_params)
| AsyncFunctionDef(identifier name, arguments args,
stmt* body, expr* decorator_list, expr? returns,
string? type_comment, type_param* type_params)
| ClassDef(identifier name,
expr* bases,
keyword* keywords,
stmt* body,
expr* decorator_list,
type_param* type_params)
| Return(expr? value)
| Delete(expr* targets)
| Assign(expr* targets, expr value, string? type_comment)
| TypeAlias(expr name, type_param* type_params, expr value)
| 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)
type_param = TypeVar(identifier name, expr? bound, expr? default_value)
| ParamSpec(identifier name, expr? default_value)
| TypeVarTuple(identifier name, expr? default_value)
attributes (int lineno, int col_offset, int end_lineno, int end_col_offset)
}
Классы узлов
-
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().
-
_field_types -
Атрибут
_field_typesкаждого конкретного класса представляет собой словарь, сопоставляющий имена полей (также перечисленные в_fields) с их типами.>>> ast.TypeVar._field_types {'name': <class 'str'>, 'bound': ast.expr | None, 'default_value': ast.expr | None}Добавлен в версии 3.13.
-
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(ast.USub(), ast.Constant(5, lineno=0, col_offset=0), lineno=0, col_offset=0)Если поле, которое необязательно в грамматике, опущено из конструктора, оно по умолчанию устанавливается в
None. Если поле списка опущено, оно по умолчанию устанавливается в пустой список. Если опущено поле типаast.expr_context, оно по умолчанию устанавливается вLoad(). Если опущено любое другое поле, генерируется предупреждениеDeprecationWarning, и узел AST не будет содержать это поле. В Python 3.15 это условие вызовет ошибку. -
Изменено в версии 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. Тем временем, создание их экземпляров вернёт экземпляр другого класса.
Устарело начиная с версии 3.13, будет удалено в версии 3.15: Предыдущие версии Python разрешали создание узлов AST, которым не хватало необходимых полей. Аналогично, конструкторы узлов AST допускали произвольные именованные аргументы, которые устанавливались в качестве атрибутов узла AST, даже если они не совпадали ни с одним из полей узла AST. Это поведение устарело и будет удалено в Python 3.15.
Примечание
Описание конкретных классов узлов, показанных здесь, изначально было адаптировано из замечательного проекта 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))])
-
class ast.Expression(body) -
Один Python-выражение выражения ввода. Тип узла генерируется функцией
ast.parse(), когда режим равен"eval".body— один узел, один из типов выражений.>>> print(ast.dump(ast.parse('123', mode='eval'), indent=4)) Expression( body=Constant(value=123))
-
class ast.Interactive(body) -
Один интерактивный ввод, как в Интерактивном режиме. Тип узла генерируется функцией
ast.parse(), когда режим равен"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()когда режим равен"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, но также и неизменяемыми контейнерными типами (кортежи и замороженные множества), если все их элементы являются константами.>>> print(ast.dump(ast.parse('123', mode='eval'), indent=4)) Expression( body=Constant(value=123))
-
class ast.FormattedValue(value, conversion, format_spec) -
Узел, представляющий отдельное поле форматирования в строке f-строки. Если строка содержит единственное поле форматирования и ничего больше, узел может быть изолирован, в противном случае он появляется в
JoinedStr.-
value— это любой узел выражения (такой как литерал, переменная или вызов функции). -
conversion— это целое число:- -1: без форматирования
- 115:
!sформатирование строк - 114:
!rформатирование repr - 97:
!aформатирование ascii
-
format_spec— это узелJoinedStr, представляющий форматирование значения, илиNone, если форматирование не было указано. Обаconversionиformat_specмогут быть установлены одновременно.
-
-
class ast.JoinedStr(values) -
F-строка, состоящая из серии узлов
FormattedValueиConstant.>>> print(ast.dump(ast.parse('f"sin({a}) is {sin(a):.3}"', mode='eval'), indent=4)) Expression( body=JoinedStr( values=[ Constant(value='sin('), FormattedValue( value=Name(id='a', ctx=Load()), conversion=-1), Constant(value=') is '), FormattedValue( value=Call( func=Name(id='sin', ctx=Load()), args=[ Name(id='a', ctx=Load())]), 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()))]) >>> print(ast.dump(ast.parse('a = 1'), indent=4)) Module( body=[ Assign( targets=[ Name(id='a', ctx=Store())], value=Constant(value=1))]) >>> print(ast.dump(ast.parse('del a'), indent=4)) Module( body=[ Delete( targets=[ Name(id='a', ctx=Del())])])
-
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()))])
Выражения
-
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())))])
-
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.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, представляющих аргументы, переданные по имени.
Аргументы
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 создается оператором присваивания выражений (также известным как оператор walrus). В отличие от узла
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)))Добавлен в версии 3.8.
Подскрипты
-
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()), 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()), 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()), 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())]), generators=[ comprehension( target=Name(id='line', ctx=Store()), iter=Name(id='file', ctx=Load()), is_async=0), comprehension( target=Name(id='c', ctx=Store()), iter=Name(id='line', ctx=Load()), 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()), 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))]) >>> 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()))]) -
-
class ast.AnnAssign(target, annotation, value, simple) -
Присваивание с аннотацией типа.
target— один узел, который может бытьName,AttributeилиSubscript.annotation— это аннотация, например, узелConstantилиName.value— это один необязательный узел.simpleвсегда равно либо 0 (указывает на «сложный» целевой объект), либо 1 (указывает на «простой» целевой объект). «Простой» целевой объект состоит только из узлаName, который не находится между скобками; все остальные целевые объекты считаются сложными. Только простые целевые объекты появляются в словаре__annotations__модулей и классов.>>> 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)]) >>> 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)]) >>> 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)]) >>> 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)])
-
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))])
-
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()))])
-
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()))])
-
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())])])
-
class ast.Pass -
Оператор
pass.>>> print(ast.dump(ast.parse('pass'), indent=4)) Module( body=[ Pass()])
-
class ast.TypeAlias(name, type_params, value) -
Псевдоним типа, созданный оператором
type.name— это имя псевдонима,type_params— список параметров типа, аvalue— значение псевдонима типа.>>> print(ast.dump(ast.parse('type Alias = int'), indent=4)) Module( body=[ TypeAlias( name=Name(id='Alias', ctx=Store()), value=Name(id='int', ctx=Load()))])Добавлен в версии 3.12.
Другие операторы, применимые только внутри функций или циклов, описаны в других разделах.
Импорты
-
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')])])
-
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)])
-
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)])
Управление потоком
Примечание
Необязательные фрагменты кода, такие как 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))])])])
-
class ast.For(target, iter, body, orelse, type_comment) -
Цикл
for.targetсодержит переменные, к которым цикл обращается, как один узелName,Tuple,List,AttributeилиSubscript.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))])]) -
-
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))])])
-
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()])])])
-
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))])])
-
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))])])])Добавлен в версии 3.11.
-
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()])])])
-
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())]))])])
Сопоставление с образцом
-
class ast.Match(subject, cases) -
Оператор
match.subjectсодержит объект, подвергающийся сопоставлению (объект, с которым сравниваются варианты), аcasesсодержит итерируемый список узловmatch_caseс различными вариантами.Добавлена в версии 3.10.
-
class ast.match_case(pattern, guard, body) -
Один вариант сопоставления в операторе
match.patternсодержит шаблон сопоставления, с которым будет сравниваться объект. Обратите внимание, что узлыAST, созданные для шаблонов, отличаются от узлов, созданных для выражений, даже если их синтаксис одинаков.Атрибут
guardсодержит выражение, которое будет вычислено, если шаблон соответствует объекту.bodyсодержит список узлов для выполнения, если шаблон соответствует и результат вычисления выражения условия истинен.>>> 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())), body=[ Expr( value=Constant(value=Ellipsis))])])])Добавлена в версии 3.10.
-
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))])])])Добавлена в версии 3.10.
-
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))])])])Добавлена в версии 3.10.
-
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))])])])Добавлена в версии 3.10.
-
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))])])])Добавлена в версии 3.10.
-
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(rest='rest'), body=[ Expr( value=Constant(value=Ellipsis))])])])Добавлена в версии 3.10.
-
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))]), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchClass( cls=Name(id='Point3D', ctx=Load()), 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))])])])Добавлена в версии 3.10.
-
class ast.MatchAs(pattern, name) -
Шаблон «as-pattern», шаблон захвата или шаблон подстановочного знака.
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))])])])Добавлена в версии 3.10.
-
class ast.MatchOr(patterns) -
Шаблон «or-pattern». Шаблон «or-pattern» по очереди сопоставляет каждый из его подшаблонов с объектом до тех пор, пока один из них не выполнится. В таком случае «or-pattern» считается выполненным. Если ни один из подшаблонов не выполнится, шаблон «or-pattern» не выполняется. Атрибут
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))])])])Добавлена в версии 3.10.
Параметры типов
Параметры типов могут существовать для классов, функций и псевдонимов типов.
-
class ast.TypeVar(name, bound, default_value) -
Переменная типа
typing.TypeVar.name— имя переменной типа.bound— ограничение или ограничения, если таковые имеются. ЕслиboundявляетсяTuple, это представляет ограничения; в противном случае это представляет ограничение.default_value— значение по умолчанию; если уTypeVarнет значения по умолчанию, этот атрибут будет установлен вNone.>>> print(ast.dump(ast.parse("type Alias[T: int = bool] = list[T]"), indent=4)) Module( body=[ TypeAlias( name=Name(id='Alias', ctx=Store()), type_params=[ TypeVar( name='T', bound=Name(id='int', ctx=Load()), default_value=Name(id='bool', ctx=Load()))], value=Subscript( value=Name(id='list', ctx=Load()), slice=Name(id='T', ctx=Load()), ctx=Load()))])Добавлена в версии 3.12.
Изменено в версии 3.13: Добавлен параметр default_value.
-
class ast.ParamSpec(name, default_value) -
Спецификация параметра
typing.ParamSpec.name— имя спецификации параметра.default_value— значение по умолчанию; если уParamSpecнет значения по умолчанию, этот атрибут будет установлен вNone.>>> print(ast.dump(ast.parse("type Alias[**P = (int, str)] = Callable[P, int]"), indent=4)) Module( body=[ TypeAlias( name=Name(id='Alias', ctx=Store()), type_params=[ ParamSpec( name='P', default_value=Tuple( elts=[ Name(id='int', ctx=Load()), Name(id='str', ctx=Load())], ctx=Load()))], value=Subscript( value=Name(id='Callable', ctx=Load()), slice=Tuple( elts=[ Name(id='P', ctx=Load()), Name(id='int', ctx=Load())], ctx=Load()), ctx=Load()))])Добавлена в версии 3.12.
Изменено в версии 3.13: Добавлен параметр default_value.
-
class ast.TypeVarTuple(name, default_value) -
Кортеж переменных типа
typing.TypeVarTuple.name— имя кортежа переменных типа.default_value— значение по умолчанию; если уTypeVarTupleнет значения по умолчанию, этот атрибут будет установлен вNone.>>> print(ast.dump(ast.parse("type Alias[*Ts = ()] = tuple[*Ts]"), indent=4)) Module( body=[ TypeAlias( name=Name(id='Alias', ctx=Store()), type_params=[ TypeVarTuple( name='Ts', default_value=Tuple(ctx=Load()))], value=Subscript( value=Name(id='tuple', ctx=Load()), slice=Tuple( elts=[ Starred( value=Name(id='Ts', ctx=Load()), ctx=Load())], ctx=Load()), ctx=Load()))])Добавлена в версии 3.12.
Изменено в версии 3.13: Добавлен параметр default_value.
Определения функций и классов
-
class ast.FunctionDef(name, args, body, decorator_list, returns, type_comment, type_params) -
Определение функции.
-
name— это строковое представление имени функции. -
args— узелarguments. -
body— список узлов внутри функции. -
decorator_list— список декораторов, которые нужно применить, начиная с самого внешнего (первый в списке будет применён последним). -
returns— аннотация возвращаемого значения. -
type_params— список параметров типа.
-
type_comment -
type_comment— необязательная строка с аннотацией типа в виде комментария.
Изменено в версии 3.12: Добавлен
type_params. -
-
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( args=[ arg(arg='x'), arg(arg='y')]), body=Constant(value=Ellipsis)))])
-
class ast.arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults, kwarg, defaults) -
Аргументы функции.
-
posonlyargs,argsиkwonlyargs— списки узловarg. -
varargиkwarg— отдельные узлыarg, относящиеся к*args, **kwargsпараметрам. -
kw_defaults— список значений по умолчанию для аргументов только с ключевыми словами. Если значение отсутствует, соответствующий аргумент обязателен. -
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( 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'))]) -
-
class ast.Return(value) -
Оператор
return.>>> print(ast.dump(ast.parse('return 4'), indent=4)) Module( body=[ Return( value=Constant(value=4))])
-
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())))]) >>> print(ast.dump(ast.parse('yield from x'), indent=4)) Module( body=[ Expr( value=YieldFrom( value=Name(id='x', ctx=Load())))])
-
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'])]) >>> print(ast.dump(ast.parse('nonlocal x,y,z'), indent=4)) Module( body=[ Nonlocal( names=[ 'x', 'y', 'z'])])
-
class ast.ClassDef(name, bases, keywords, body, decorator_list, type_params) -
Определение класса.
-
name— строковое представление имени класса -
bases— список узлов для явно указанных базовых классов. -
keywords— список узловkeyword, в основном для ‘metaclass’. Другие ключевые слова будут переданы metaclass, в соответствии с PEP 3115. -
body— список узлов, представляющих код внутри определения класса. -
decorator_list— список узлов, как вFunctionDef. -
type_params— список параметров типа.
>>> 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())])])Изменено в версии 3.12: Добавлен
type_params. -
Асинхронные и ожидающие операции
-
class ast.AsyncFunctionDef(name, args, body, decorator_list, returns, type_comment, type_params) -
Определение
async defфункции. Имеет те же поля, что иFunctionDef.Изменено в версии 3.12: Добавлен
type_params.
-
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(),
body=[
Expr(
value=Await(
value=Call(
func=Name(id='other_func', ctx=Load()))))])])
-
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, optimize=-1) -
Разбор исходного кода в узел AST. Эквивалентно
compile(source, filename, mode, flags=FLAGS_VALUE, optimize=optimize), гдеFLAGS_VALUEравноast.PyCF_ONLY_ASTеслиoptimize <= 0иast.PyCF_OPTIMIZED_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, 7)(и она может увеличиться в будущих версиях Python); наибольшая —sys.version_info[0:2]. «Лучшая попытка» означает, что нет гарантии, что разбор (или успех разбора) будет таким же, как при запуске на версии Python, соответствующейfeature_version.Если исходный код содержит нулевой символ (
\0), генерируется исключениеValueError.Предупреждение
Обратите внимание, что успешный разбор исходного кода в объект AST не гарантирует, что предоставленный исходный код является корректным кодом Python, который можно выполнить, так как на этапе компиляции могут быть подняты дополнительные исключения
SyntaxError. Например, исходный кодreturn 42генерирует допустимый узел AST для инструкции return, но его нельзя скомпилировать отдельно (он должен быть внутри узла функции).В частности,
ast.parse()не будет выполнять проверки области видимости, которые выполняет этап компиляции.Предупреждение
Возможно аварийное завершение интерпретатора Python из-за ограничений глубины стека в компиляторе AST Python при достаточно большом/сложном входном строке.
Изменено в версии 3.8: Добавлены
type_comments,mode='func_type'иfeature_version.Изменено в версии 3.13: Минимально поддерживаемая версия для
feature_versionтеперь(3, 7). Аргументoptimizeбыл добавлен.
-
ast.unparse(ast_obj) -
Преобразование объекта
ast.ASTв строку с кодом, который создал бы эквивалентный объектast.ASTпри повторном разборе с помощьюast.parse().Предупреждение
Сгенерированная строка кода не обязательно будет равна исходному коду, который сгенерировал объект
ast.AST(без каких-либо оптимизаций компилятора, таких как константные кортежи/замороженные множества).Предупреждение
Попытка преобразования очень сложного выражения приведет к
RecursionError.Добавлена в версии 3.9.
-
ast.literal_eval(node_or_string) -
Вычисление узла выражения или строки, содержащей только литерал Python или представление контейнера. Предоставленная строка или узел может содержать только следующие структуры литералов Python: строки, байты, числа, кортежи, списки, словари, множества, булевы значения,
NoneиEllipsis.Это можно использовать для вычисления строк, содержащих значения Python, без необходимости разбора значений самостоятельно. Она не способна вычислять произвольно сложные выражения, например, включающие операторы или индексирование.
Эта функция в прошлом документировалась как «безопасная» без определения того, что это означает. Это было вводящее в заблуждение. Она специально разработана для того, чтобы не выполнять код Python, в отличие от более общей функции
eval(). Нет пространства имен, нет поиска имен или возможности вызова. Но она не защищена от атак: относительно небольшой вход может привести к исчерпанию памяти или к переполнению стека C, вызывая аварийное завершение процесса. Также существует вероятность чрезмерного потребления процессора, что может стать причиной отказа в обслуживании некоторых входных данных. Поэтому вызывать ее с небезопасными данными не рекомендуется.Предупреждение
Возможно аварийное завершение интерпретатора Python из-за ограничений глубины стека в компиляторе AST 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) -
Возвращает кортеж
(fieldname, value)для каждого поля вnode._fields, присутствующего в node.
-
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, show_empty=False) -
Возвращает отформатированный вывод дерева в node. Это в основном полезно для отладки. Если annotate_fields истинно (по умолчанию), возвращаемая строка будет показывать имена и значения полей. Если annotate_fields ложно, результат будет более компактным, опуская недвусмысленные имена полей. Атрибуты, такие как номера строк и смещения столбцов, по умолчанию не выводятся. Если это нужно, include_attributes можно установить в true.
Если indent — целое число или строка, больше или равно нулю, то дерево будет отформатировано с заданным уровнем отступа. Уровень отступа 0, отрицательный или
""будут вставлять только новые строки.None(по умолчанию) выбирает однострочный вывод. Использование положительного целого значения для indent вставляет отступы в виде пробелов на каждом уровне. Если indent — строка (например,"\t"), эта строка используется для отступа каждого уровня.Если show_empty —
False(по умолчанию), пустые списки и поля, которыеNoneбудут опущены из вывода.Изменено в версии 3.9: Добавлен параметр indent.
Изменено в версии 3.13: Добавлен параметр show_empty.
>>> print(ast.dump(ast.parse("""\ ... async def f(): ... await other_func() ... """), indent=4, show_empty=True)) 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_params=[])], type_ignores=[])
Флаги компилятора
Следующие флаги можно передать в compile(), чтобы изменить влияние на компиляцию программы:
-
ast.PyCF_ALLOW_TOP_LEVEL_AWAIT -
Включает поддержку ожиданий на верхнем уровне
await,async for,async withи асинхронных генераторов.Добавлен в версии 3.8.
-
ast.PyCF_ONLY_AST -
Генерирует и возвращает абстрактное синтаксическое дерево вместо возвращения скомпилированного объекта кода.
-
ast.PyCF_OPTIMIZED_AST -
Возвращённое AST оптимизируется в соответствии с аргументом optimize в
compile()илиast.parse().Добавлен в версии 3.13.
Использование в командной строке
Добавлена в версии 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 и выводится в стандартный вывод. В противном случае содержимое считывается со стандартного ввода.
См. также
Green Tree Snakes, внешний ресурс документации, содержит подробную информацию о работе с Python AST.
ASTTokens аннотирует Python AST с позициями токенов и текста в исходном коде, который их породил. Это полезно для инструментов, которые производят преобразования исходного кода.
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.13/library/ast.html