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, даже если они не соответствовали ни одному из его полей. Такое поведение устарело и будет удалено в Python 3.15.
Примечание
Описания конкретных классов узлов, приведённые здесь, изначально были адаптированы из замечательного проекта Green Tree Snakes и материалов всех его участников.
Корневые узлы
-
class ast.Module(body, type_ignores) -
Модуль Python, соответствующий вводу из файла. Тип узла, создаваемый функцией
ast.parse()в режиме mode по умолчанию"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(), если параметр 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. Представленными значениями могут быть экземплярыstr,bytes,int,float,complexиbool, а также константыNoneиEllipsis.>>> 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())]), 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()))]) >>> 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 создаётся оператором присваивания-выражения (также известным как оператор-морж). В отличие от узла
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содержит список узлов для выполнения, если образец соответствует объекту и результат вычисления выражения-условия равен 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())), 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содержит образец, с которым будет сопоставлен проверяемый объект. Если образец равен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) -
Образец сопоставления вида «или». Такой образец по очереди сопоставляет каждый из своих вложенных образцов с проверяемым объектом, пока один из них не окажется успешным. В этом случае образец «или» считается успешным. Если ни один вложенный образец не подходит, образец «или» считается неуспешным. Атрибут
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.TypeIgnore(lineno, tag) -
Комментарий
# type: ignore, расположенный на строке lineno. tag — необязательная метка, заданная в форме# type: ignore <tag>.>>> print(ast.dump(ast.parse('x = 1 # type: ignore', type_comments=True), indent=4)) Module( body=[ Assign( targets=[ Name(id='x', ctx=Store())], value=Constant(value=1))], type_ignores=[ TypeIgnore(lineno=1, tag='')]) >>> print(ast.dump(ast.parse('x: bool = 1 # type: ignore[assignment]', type_comments=True), indent=4)) Module( body=[ AnnAssign( target=Name(id='x', ctx=Store()), annotation=Name(id='bool', ctx=Load()), value=Constant(value=1), simple=1)], type_ignores=[ TypeIgnore(lineno=1, tag='[assignment]')])Примечание
Узлы
TypeIgnoreне создаются, если параметр type_comments имеет значениеFalse(по умолчанию). Подробнее см.ast.parse().Добавлено в версии 3.8.
Параметры типа
Параметры типа могут использоваться в классах, функциях и псевдонимах типов.
-
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=List( 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— список значений по умолчанию для аргументов, передаваемых только по имени. Если одно из значений равно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( 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». Остальные именованные аргументы передаются метаклассу согласно 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. -
Асинхронность и await
-
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()не выполняет проверку областей видимости, которая проводится на этапе компиляции.Предупреждение
Из-за ограничений глубины стека в компиляторе AST Python интерпретатор Python может завершиться с аварийной ошибкой при обработке достаточно большой или сложной строки.
Изменено в версии 3.8: Добавлены
type_comments,mode='func_type'иfeature_version.Изменено в версии 3.13: Теперь минимальная поддерживаемая версия для
feature_version—(3, 7). Добавлен аргументoptimize.
-
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, show_empty=False) -
Возвращает отформатированное представление дерева в node. Эта функция главным образом полезна для отладки. Если annotate_fields имеет значение true (по умолчанию), возвращаемая строка будет содержать имена полей и их значения. Если annotate_fields имеет значение false, строка результата будет компактнее, поскольку однозначные имена полей будут опущены. Такие атрибуты, как номера строк и смещения столбцов, по умолчанию не выводятся. Чтобы включить их, можно задать для include_attributes значение true.
Если indent — неотрицательное целое число или строка, дерево будет красиво отформатировано с указанным уровнем отступа. Уровень отступа 0, отрицательное значение или
""приведёт только к добавлению символов новой строки.None(значение по умолчанию) выбирает представление в одну строку. При положительном целочисленном значении отступа на каждом уровне добавляется указанное количество пробелов. Если 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, а результат выводится в stdout. В противном случае содержимое считывается из stdin.
См. также
Green Tree Snakes — внешний ресурс документации с полезными сведениями о работе с AST Python.
ASTTokens добавляет к AST Python аннотации с расположением токенов и текста в исходном коде, на основе которого они были созданы. Это полезно для инструментов преобразования исходного кода.
leoAst.py объединяет представления программ Python на основе токенов и деревьев разбора, добавляя двусторонние связи между токенами и узлами AST.
LibCST разбирает код в конкретное синтаксическое дерево, похожее на дерево AST и сохраняющее все детали форматирования. Оно полезно для создания приложений автоматического рефакторинга (codemod) и линтеров.
Parso — это анализатор Python, поддерживающий восстановление после ошибок и разбор с сохранением исходного текста для разных версий Python (в нескольких версиях Python). Parso также умеет находить несколько синтаксических ошибок в файле Python.
© 2001–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/ast.html