ast — Абстрактные синтаксические деревья¶
Исходный код: Lib/ast.py
Модуль ast помогает приложениям на Python обрабатывать деревья грамматики абстрактного синтаксиса Python. Сам абстрактный синтаксис может меняться с каждым выпуском Python; этот модуль помогает программно определить, как выглядит текущая грамматика.
Абстрактное синтаксическое дерево может быть сгенерировано путем передачи ast.PyCF_ONLY_AST в качестве флага встроенной функции compile() или с помощью вспомогательного средства parse(), предоставляемого в этом модуле. Результатом будет дерево объектов, все классы которых наследуются от ast.AST. Абстрактное синтаксическое дерево может быть скомпилировано в объект кода Python с помощью встроенной функции compile().
Абстрактная грамматика¶
Абстрактная грамматика в настоящее время определяется следующим образом:
Классы узлов¶
- class ast.AST¶
Это основа всех классов узлов AST. Сами классы узлов получены из файла
Parser/Python.asdl, который воспроизводится above. Они определены в модуле_astC и повторно экспортированы вast.В абстрактной грамматике для каждого левого символа определен один класс (например,
ast.stmtилиast.expr). Кроме того, для каждого конструктора с правой стороны определен один класс; эти классы наследуются от классов для деревьев с левой стороны. Например,ast.BinOpнаследуется отast.expr. Для производственных правил с альтернативами (они же «суммы») класс левой части является абстрактным: когда-либо создаются только экземпляры определенных узлов конструктора.- _fields¶
Каждый конкретный класс имеет атрибут
_fields, который задает имена всех дочерних узлов.Каждый экземпляр конкретного класса имеет один атрибут для каждого дочернего узла типа, определенного в грамматике. Например, экземпляры
ast.BinOpимеют атрибутleftтипаast.expr.Если в грамматике эти атрибуты помечены как необязательные (с помощью вопросительного знака), то их значением может быть
None. Если атрибуты могут содержать ноль или более значений (помечены звездочкой), значения представляются в виде списков Python. Все возможные атрибуты должны присутствовать и иметь допустимые значения при компиляции AST с помощьюcompile().
- lineno¶
- col_offset¶
- end_lineno¶
- end_col_offset¶
Экземпляры подклассов
ast.exprиast.stmtимеют атрибутыlineno,col_offset,end_lineno, иend_col_offset.linenoиend_lineno- это номера первой и последней строк исходного текста (индексируются на 1, поэтому первая строка равна строке 1), аcol_offsetиend_col_offset- соответствующие UTFСмещение на -8 байт первого и последнего токенов, сгенерировавших узел. Смещение UTF-8 записывается потому, что синтаксический анализатор использует UTF-8 внутренне.Обратите внимание, что конечные позиции не требуются компилятору и, следовательно, являются необязательными. Конечное смещение находится после последнего символа, например, можно получить исходный сегмент узла однострочного выражения, используя
source_line[node.col_offset : node.end_col_offset].
Конструктор класса
ast.Tанализирует свои аргументы следующим образом:Если есть позиционные аргументы, то их должно быть столько, сколько элементов в
T._fields; они будут назначены в качестве атрибутов этих имен.Если есть аргументы ключевого слова, они будут присваивать атрибутам с одинаковыми именами заданные значения.
Например, чтобы создать и заполнить узел
ast.UnaryOp, вы могли бы использоватьnode = ast.UnaryOp() node.op = ast.USub() node.operand = ast.Constant() node.operand.value = 5 node.operand.lineno = 0 node.operand.col_offset = 0 node.lineno = 0 node.col_offset = 0
или более компактный
node = ast.UnaryOp(ast.USub(), ast.Constant(5, lineno=0, col_offset=0), lineno=0, col_offset=0)
Изменено в версии 3.8: Класс ast.Constant теперь используется для всех констант.
Изменено в версии 3.9: Простые индексы представлены по их значению, расширенные срезы представлены в виде кортежей.
Не рекомендуется, начиная с версии 3.8: Старые классы ast.Num, ast.Str, ast.Bytes, ast.NameConstant и ast.Ellipsis все еще доступны, но они будут удалены в будущих версиях Python. В то же время при их создании будет возвращен экземпляр другого класса.
Не рекомендуется, начиная с версии 3.9: Старые классы ast.Index и ast.ExtSlice все еще доступны, но они будут удалены в будущих версиях Python. Тем временем при их создании будет возвращен экземпляр другого класса.
Примечание
Описания конкретных классов узлов, представленные здесь, изначально были адаптированы из проекта fantastic Green Tree Snakes и всех его участников.
Корневые узлы¶
- class ast.Module(body, type_ignores)¶
Модуль Python, как и в случае с file input. Тип узла, сгенерированный
ast.parse()в режиме"exec"по умолчанию*.тело - это
listмодуля Заявления.type_ignores - это
listтипа игнорируемых комментариев модуля; более подробную информацию смотрите вast.parse().>>> print(ast.dump(ast.parse('x = 1'), indent=4)) Module( body=[ Assign( targets=[ Name(id='x', ctx=Store())], value=Constant(value=1))], type_ignores=[])
- class ast.Expression(body)¶
Один Python expression input. Тип узла генерируется с помощью
ast.parse(), когда mode равен"eval".body - это отдельный узел, один из expression types.
>>> print(ast.dump(ast.parse('123', mode='eval'), indent=4)) Expression( body=Constant(value=123))
- class ast.Interactive(body)¶
Одиночный interactive input, как в Интерактивный режим. Тип узла, генерируемый
ast.parse(), когда mode равен"single".body - это
listиз statement nodes.>>> 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)¶
Представление типа comments старого образца для функций, поскольку версии Python до 3.5 не поддерживали аннотации PEP 484. Тип узла генерируется с помощью
ast.parse(), когда mode равен"func_type".Комментарии такого типа будут выглядеть следующим образом:
def sum_two_number(a, b): # type: (int, int) -> int return a + b
argtypes - это
listиз expression nodes.возвращает одинарный expression node.
>>> 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повторное форматирование97:
!aформатирование в формате ascii
format_spec- это узелJoinedStr, представляющий форматирование значения, илиNone, если формат не был указан. Какconversion, так иformat_specмогут быть установлены одновременно.
- class ast.JoinedStr(values)¶
F-строка, состоящая из последовательности узлов
FormattedValueиConstant.>>> print(ast.dump(ast.parse('f"sin({a}) is {sin(a):.3}"', mode='eval'), indent=4)) Expression( body=JoinedStr( values=[ Constant(value='sin('), FormattedValue( value=Name(id='a', ctx=Load()), conversion=-1), Constant(value=') is '), FormattedValue( value=Call( func=Name(id='sin', ctx=Load()), args=[ Name(id='a', ctx=Load())], keywords=[]), conversion=-1, format_spec=JoinedStr( values=[ Constant(value='.3')]))]))
- class ast.List(elts, ctx)¶
- class ast.Tuple(elts, ctx)¶
Список или кортеж.
eltsсодержит список узлов, представляющих элементы.ctxравноStore, если контейнер является объектом назначения (т.е.(x,y)=something), иLoadв противном случае.>>> print(ast.dump(ast.parse('[1, 2, 3]', mode='eval'), indent=4)) Expression( body=List( elts=[ Constant(value=1), Constant(value=2), Constant(value=3)], ctx=Load())) >>> print(ast.dump(ast.parse('(1, 2, 3)', mode='eval'), indent=4)) Expression( body=Tuple( elts=[ Constant(value=1), Constant(value=2), Constant(value=3)], ctx=Load()))
- class ast.Set(elts)¶
Набор.
eltsсодержит список узлов, представляющих элементы набора.>>> print(ast.dump(ast.parse('{1, 2, 3}', mode='eval'), indent=4)) Expression( body=Set( elts=[ Constant(value=1), Constant(value=2), Constant(value=3)]))
- class ast.Dict(keys, values)¶
Словарь.
keysиvaluesсодержат списки узлов, представляющих ключи и значения соответственно, в соответствующем порядке (что было бы возвращено при вызовеdictionary.keys()иdictionary.values()).При распаковке словаря с использованием словарных литералов расширяемое выражение помещается в список
values, сNoneв соответствующей позиции вkeys.>>> print(ast.dump(ast.parse('{"a":1, **d}', mode='eval'), indent=4)) Expression( body=Dict( keys=[ Constant(value='a'), None], values=[ Constant(value=1), Name(id='d', ctx=Load())]))
Переменные¶
- class ast.Name(id, ctx)¶
Имя переменной.
idсодержит имя в виде строки, аctxявляется одним из следующих типов.
- class ast.Load¶
- class ast.Store¶
- class ast.Del¶
Ссылки на переменные могут использоваться для загрузки значения переменной, присвоения ей нового значения или для ее удаления. Ссылки на переменные имеют контекст, позволяющий различать эти случаи.
>>> print(ast.dump(ast.parse('a'), indent=4)) Module( body=[ Expr( value=Name(id='a', ctx=Load()))], type_ignores=[]) >>> print(ast.dump(ast.parse('a = 1'), indent=4)) Module( body=[ Assign( targets=[ Name(id='a', ctx=Store())], value=Constant(value=1))], type_ignores=[]) >>> print(ast.dump(ast.parse('del a'), indent=4)) Module( body=[ Delete( targets=[ Name(id='a', ctx=Del())])], type_ignores=[])
- class ast.Starred(value, ctx)¶
Ссылка на переменную
*var.valueсодержит переменную, обычно это узелName. Этот тип необходимо использовать при построении узлаCallс помощью*args.>>> print(ast.dump(ast.parse('a, *b = it'), indent=4)) Module( body=[ Assign( targets=[ Tuple( elts=[ Name(id='a', ctx=Store()), Starred( value=Name(id='b', ctx=Store()), ctx=Store())], ctx=Store())], value=Name(id='it', ctx=Load()))], type_ignores=[])
Выражения¶
- class ast.Expr(value)¶
Когда выражение, такое как вызов функции, само по себе отображается как оператор, возвращаемое значение которого не используется и не сохраняется, оно помещается в этот контейнер.
valueсодержит один из других узлов в этом разделе, aConstant, aName,Lambda,YieldилиYieldFromузел.>>> print(ast.dump(ast.parse('-a'), indent=4)) Module( body=[ Expr( value=UnaryOp( op=USub(), operand=Name(id='a', ctx=Load())))], type_ignores=[])
- class ast.UnaryOp(op, operand)¶
Унарная операция.
op- это оператор, аoperand- любой узел выражения.
- class ast.UAdd¶
- class ast.USub¶
- class ast.Not¶
- class ast.Invert¶
Токены унарных операторов.
Not- это ключевое словоnot,Invert- это оператор~.>>> print(ast.dump(ast.parse('not x', mode='eval'), indent=4)) Expression( body=UnaryOp( op=Not(), operand=Name(id='x', ctx=Load())))
- class ast.BinOp(left, op, right)¶
Двоичная операция (например, сложение или деление).
op- это оператор, аleftиright- это любые узлы выражения.>>> print(ast.dump(ast.parse('x + y', mode='eval'), indent=4)) Expression( body=BinOp( left=Name(id='x', ctx=Load()), op=Add(), right=Name(id='y', ctx=Load())))
- class ast.Add¶
- class ast.Sub¶
- class ast.Mult¶
- class ast.Div¶
- class ast.FloorDiv¶
- class ast.Mod¶
- class ast.Pow¶
- class ast.LShift¶
- class ast.RShift¶
- class ast.BitOr¶
- class ast.BitXor¶
- class ast.BitAnd¶
- class ast.MatMult¶
Токены бинарных операторов.
- class ast.BoolOp(op, values)¶
Логическая операция, «или» или «и».
opравноOrилиAnd.valuesэто соответствующие значения. Последовательные операции с одним и тем же оператором, такие какa or b or c, сворачиваются в один узел с несколькими значениями.Это не включает
not, который являетсяUnaryOp.>>> print(ast.dump(ast.parse('x or y', mode='eval'), indent=4)) Expression( body=BoolOp( op=Or(), values=[ Name(id='x', ctx=Load()), Name(id='y', ctx=Load())]))
- class ast.Compare(left, ops, comparators)¶
Сравнение двух или более значений.
left- это первое значение в сравнении,ops- список операторов, аcomparators- список значений после первого элемента в сравнении.>>> print(ast.dump(ast.parse('1 <= a < 10', mode='eval'), indent=4)) Expression( body=Compare( left=Constant(value=1), ops=[ LtE(), Lt()], comparators=[ Name(id='a', ctx=Load()), Constant(value=10)]))
- class ast.Eq¶
- class ast.NotEq¶
- class ast.Lt¶
- class ast.LtE¶
- class ast.Gt¶
- class ast.GtE¶
- class ast.Is¶
- class ast.IsNot¶
- class ast.In¶
- class ast.NotIn¶
Токены оператора сравнения.
- class ast.Call(func, args, keywords)¶
Вызов функции.
func- это функция, которая часто является объектомNameилиAttribute. Из аргументов:argsсодержит список аргументов, передаваемых по позиции.keywordsсодержит список объектовkeyword, представляющих аргументы, передаваемые с помощью ключевого слова.
При создании узла
Callтребуютсяargsиkeywords, но они могут быть пустыми списками.>>> print(ast.dump(ast.parse('func(a, b=c, *d, **e)', mode='eval'), indent=4)) Expression( body=Call( func=Name(id='func', ctx=Load()), args=[ Name(id='a', ctx=Load()), Starred( value=Name(id='d', ctx=Load()), ctx=Load())], keywords=[ keyword( arg='b', value=Name(id='c', ctx=Load())), keyword( value=Name(id='e', ctx=Load()))]))
- class ast.keyword(arg, value)¶
Аргумент ключевого слова для вызова функции или определения класса.
arg- это необработанная строка имени параметра,value- это узел, который нужно передать.
- class ast.IfExp(test, body, orelse)¶
Выражение, такое как
a if b else c. Каждое поле содержит один узел, поэтому в следующем примере все три являются узламиName.>>> print(ast.dump(ast.parse('a if b else c', mode='eval'), indent=4)) Expression( body=IfExp( test=Name(id='b', ctx=Load()), body=Name(id='a', ctx=Load()), orelse=Name(id='c', ctx=Load())))
- class ast.Attribute(value, attr, ctx)¶
Доступ к атрибуту, например.
d.keys.value- это узел, обычно aName.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)))
Индексация¶
- class ast.Subscript(value, slice, ctx)¶
Индекс, такой как
l[1].value, - это объект, на который делается подписка (обычно это последовательность или отображение).slice- это индекс, фрагмент или ключ. Это может бытьTupleи содержатьSlice.ctxisLoad,StoreилиDelв зависимости от действия, выполняемого с индексом .>>> print(ast.dump(ast.parse('l[1:2, 3]', mode='eval'), indent=4)) Expression( body=Subscript( value=Name(id='l', ctx=Load()), slice=Tuple( elts=[ Slice( lower=Constant(value=1), upper=Constant(value=2)), Constant(value=3)], ctx=Load()), ctx=Load()))
- class ast.Slice(lower, upper, step)¶
Обычная нарезка (в форме
lower:upperилиlower:upper:step). Может выполняться только внутри поля slice вSubscript, либо непосредственно, либо как элемент вTuple.>>> print(ast.dump(ast.parse('l[1:2]', mode='eval'), indent=4)) Expression( body=Subscript( value=Name(id='l', ctx=Load()), slice=Slice( lower=Constant(value=1), upper=Constant(value=2)), ctx=Load()))
Понимания¶
- class ast.ListComp(elt, generators)¶
- class ast.SetComp(elt, generators)¶
- class ast.GeneratorExp(elt, generators)¶
- class ast.DictComp(key, value, generators)¶
Перечислите и задайте значения, выражения-генераторы и значения по словарю.
elt(илиkeyиvalue) - это отдельный узел, представляющий часть, которая будет оцениваться для каждого элемента.generators- это списокcomprehensionузлов.>>> print(ast.dump(ast.parse('[x for x in numbers]', mode='eval'), indent=4)) Expression( body=ListComp( elt=Name(id='x', ctx=Load()), generators=[ comprehension( target=Name(id='x', ctx=Store()), iter=Name(id='numbers', ctx=Load()), ifs=[], is_async=0)])) >>> print(ast.dump(ast.parse('{x: x**2 for x in numbers}', mode='eval'), indent=4)) Expression( body=DictComp( key=Name(id='x', ctx=Load()), value=BinOp( left=Name(id='x', ctx=Load()), op=Pow(), right=Constant(value=2)), generators=[ comprehension( target=Name(id='x', ctx=Store()), iter=Name(id='numbers', ctx=Load()), ifs=[], is_async=0)])) >>> print(ast.dump(ast.parse('{x for x in numbers}', mode='eval'), indent=4)) Expression( body=SetComp( elt=Name(id='x', ctx=Load()), generators=[ comprehension( target=Name(id='x', ctx=Store()), iter=Name(id='numbers', ctx=Load()), ifs=[], is_async=0)]))
- class ast.comprehension(target, iter, ifs, is_async)¶
Одно предложение
forв понятии.target- это ссылка для использования для каждого элемента - обычно это узелNameилиTuple.iter- это объект для итерации over.ifs- это список тестовых выражений: каждое предложениеforможет содержать несколькоifs.is_asyncуказывает на асинхронность понимания (используетсяasync forвместоfor). Значение является целым числом (0 или 1).>>> print(ast.dump(ast.parse('[ord(c) for line in file for c in line]', mode='eval'), ... indent=4)) # Multiple comprehensions in one. Expression( body=ListComp( elt=Call( func=Name(id='ord', ctx=Load()), args=[ Name(id='c', ctx=Load())], keywords=[]), generators=[ comprehension( target=Name(id='line', ctx=Store()), iter=Name(id='file', ctx=Load()), ifs=[], is_async=0), comprehension( target=Name(id='c', ctx=Store()), iter=Name(id='line', ctx=Load()), ifs=[], is_async=0)])) >>> print(ast.dump(ast.parse('(n**2 for n in it if n>5 if n<10)', mode='eval'), ... indent=4)) # generator comprehension Expression( body=GeneratorExp( elt=BinOp( left=Name(id='n', ctx=Load()), op=Pow(), right=Constant(value=2)), generators=[ comprehension( target=Name(id='n', ctx=Store()), iter=Name(id='it', ctx=Load()), ifs=[ Compare( left=Name(id='n', ctx=Load()), ops=[ Gt()], comparators=[ Constant(value=5)]), Compare( left=Name(id='n', ctx=Load()), ops=[ Lt()], comparators=[ Constant(value=10)])], is_async=0)])) >>> print(ast.dump(ast.parse('[i async for i in soc]', mode='eval'), ... indent=4)) # Async comprehension Expression( body=ListComp( elt=Name(id='i', ctx=Load()), generators=[ comprehension( target=Name(id='i', ctx=Store()), iter=Name(id='soc', ctx=Load()), ifs=[], is_async=1)]))
Заявления¶
- class ast.Assign(targets, value, type_comment)¶
Назначение.
targets- это список узлов, аvalue- это отдельный узел.Несколько узлов в
targetsозначают присвоение одного и того же значения каждому из них. Распаковка представлена путем помещенияTupleилиListвtargets.- type_comment¶
type_comment- это необязательная строка с типом аннотации в качестве комментария.
>>> print(ast.dump(ast.parse('a = b = 1'), indent=4)) # Multiple assignment Module( body=[ Assign( targets=[ Name(id='a', ctx=Store()), Name(id='b', ctx=Store())], value=Constant(value=1))], type_ignores=[]) >>> print(ast.dump(ast.parse('a,b = c'), indent=4)) # Unpacking Module( body=[ Assign( targets=[ Tuple( elts=[ Name(id='a', ctx=Store()), Name(id='b', ctx=Store())], ctx=Store())], value=Name(id='c', ctx=Load()))], type_ignores=[])
- class ast.AnnAssign(target, annotation, value, simple)¶
Назначение с аннотацией типа.
targetпредставляет собой отдельный узел и может бытьName,AttributeилиSubscript.annotationэто аннотация, напримерConstantилиNameузел.value- это отдельный необязательный узел.simple- логическое целое число, которому присвоено значение True дляNameузла вtarget, которые не они заключены в круглые скобки и, следовательно, являются нашими именами, а не выражениями.>>> print(ast.dump(ast.parse('c: int'), indent=4)) Module( body=[ AnnAssign( target=Name(id='c', ctx=Store()), annotation=Name(id='int', ctx=Load()), simple=1)], type_ignores=[]) >>> print(ast.dump(ast.parse('(a): int = 1'), indent=4)) # Annotation with parenthesis Module( body=[ AnnAssign( target=Name(id='a', ctx=Store()), annotation=Name(id='int', ctx=Load()), value=Constant(value=1), simple=0)], type_ignores=[]) >>> print(ast.dump(ast.parse('a.b: int'), indent=4)) # Attribute annotation Module( body=[ AnnAssign( target=Attribute( value=Name(id='a', ctx=Load()), attr='b', ctx=Store()), annotation=Name(id='int', ctx=Load()), simple=0)], type_ignores=[]) >>> print(ast.dump(ast.parse('a[1]: int'), indent=4)) # Subscript annotation Module( body=[ AnnAssign( target=Subscript( value=Name(id='a', ctx=Load()), slice=Constant(value=1), ctx=Store()), annotation=Name(id='int', ctx=Load()), simple=0)], type_ignores=[])
- class ast.AugAssign(target, op, value)¶
Расширенное назначение, например
a += 1. В следующем примереtargetявляется узломNameдляx(с контекстомStore),op- этоAdd, аvalue- этоConstantсо значением, равным 1.Атрибут
targetне может принадлежать классуTupleилиList, в отличие от целевых объектовAssign.>>> print(ast.dump(ast.parse('x += 2'), indent=4)) Module( body=[ AugAssign( target=Name(id='x', ctx=Store()), op=Add(), value=Constant(value=2))], type_ignores=[])
- class ast.Raise(exc, cause)¶
Оператор
raise.exc- это объект исключения, который должен быть создан, обычно этоCallилиName, илиNoneдля автономногоraise.causeявляется необязательной частью дляyвraise x from y.>>> print(ast.dump(ast.parse('raise x from y'), indent=4)) Module( body=[ Raise( exc=Name(id='x', ctx=Load()), cause=Name(id='y', ctx=Load()))], type_ignores=[])
- class ast.Assert(test, msg)¶
Утверждение.
testсодержит условие, например, узелCompare.msgсодержит сообщение об ошибке.>>> print(ast.dump(ast.parse('assert x,y'), indent=4)) Module( body=[ Assert( test=Name(id='x', ctx=Load()), msg=Name(id='y', ctx=Load()))], type_ignores=[])
- class ast.Delete(targets)¶
Представляет собой оператор
del.targets- это список узлов, таких какName,AttributeилиSubscriptузлов.>>> print(ast.dump(ast.parse('del x,y,z'), indent=4)) Module( body=[ Delete( targets=[ Name(id='x', ctx=Del()), Name(id='y', ctx=Del()), Name(id='z', ctx=Del())])], type_ignores=[])
- class ast.Pass¶
Оператор
pass.>>> print(ast.dump(ast.parse('pass'), indent=4)) Module( body=[ Pass()], type_ignores=[])
Другие инструкции, которые применимы только внутри функций или циклов, описаны в других разделах.
Импорт¶
- class ast.Import(names)¶
Оператор импорта.
names- это списокaliasузлов.>>> print(ast.dump(ast.parse('import x,y,z'), indent=4)) Module( body=[ Import( names=[ alias(name='x'), alias(name='y'), alias(name='z')])], type_ignores=[])
- class ast.ImportFrom(module, names, level)¶
Представляет собой
from x import y.module- это необработанная строка с именем „from“, без каких-либо начальных точек, илиNoneдля таких операторов, какfrom . import foo.level- это целое число, содержащее уровень относительного импорта (0 означает абсолютный импорт).>>> print(ast.dump(ast.parse('from y import x,y,z'), indent=4)) Module( body=[ ImportFrom( module='y', names=[ alias(name='x'), alias(name='y'), alias(name='z')], level=0)], type_ignores=[])
- class ast.alias(name, asname)¶
Оба параметра представляют собой необработанные строки имен.
asnameможет бытьNone, если используется обычное имя.>>> print(ast.dump(ast.parse('from ..foo.bar import a as b, c'), indent=4)) Module( body=[ ImportFrom( module='foo.bar', names=[ alias(name='a', asname='b'), alias(name='c')], level=2)], type_ignores=[])
Поток управления¶
Примечание
Необязательные предложения, такие как else, сохраняются в виде пустого списка, если они отсутствуют.
- class ast.If(test, body, orelse)¶
Оператор
if.testсодержит один узел, например, узелCompare.bodyиorelseсодержат список узлов.elifпредложения не имеют специального представления в PAST, а скорее отображаются как дополнительные узлыIfв разделеorelseпредыдущего раздела.>>> print(ast.dump(ast.parse(""" ... if x: ... ... ... elif y: ... ... ... else: ... ... ... """), indent=4)) Module( body=[ If( test=Name(id='x', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))], orelse=[ If( test=Name(id='y', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))], orelse=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.For(target, iter, body, orelse, type_comment)¶
Цикл
for.targetсодержит переменные, которым присваивается цикл, в виде отдельного узлаName,TupleилиList.iterсодержит элемент, по которому нужно выполнить цикл, опять же как по одному узлу.bodyиorelseсодержат списки узлов для выполнения. Инструкции вorelseвыполняются, если цикл завершается нормально, а не с помощью инструкцииbreak.- type_comment¶
type_comment- это необязательная строка с типом аннотации в качестве комментария.
>>> print(ast.dump(ast.parse(""" ... for x in y: ... ... ... else: ... ... ... """), indent=4)) Module( body=[ For( target=Name(id='x', ctx=Store()), iter=Name(id='y', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))], orelse=[ Expr( value=Constant(value=Ellipsis))])], type_ignores=[])
- class ast.While(test, body, orelse)¶
Цикл
while.testсодержит условие, такое как узелCompare.>> print(ast.dump(ast.parse(""" ... while x: ... ... ... else: ... ... ... """), indent=4)) Module( body=[ While( test=Name(id='x', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))], orelse=[ Expr( value=Constant(value=Ellipsis))])], type_ignores=[])
- class ast.Break¶
- class ast.Continue¶
Операторы
breakиcontinue.>>> print(ast.dump(ast.parse("""\ ... for a in b: ... if a > 5: ... break ... else: ... continue ... ... """), indent=4)) Module( body=[ For( target=Name(id='a', ctx=Store()), iter=Name(id='b', ctx=Load()), body=[ If( test=Compare( left=Name(id='a', ctx=Load()), ops=[ Gt()], comparators=[ Constant(value=5)]), body=[ Break()], orelse=[ Continue()])], orelse=[])], type_ignores=[])
- class ast.Try(body, handlers, orelse, finalbody)¶
tryблоков. Все атрибуты представляют собой список узлов для выполнения, за исключениемhandlers, который представляет собой списокExceptHandlerузлов.>>> print(ast.dump(ast.parse(""" ... try: ... ... ... except Exception: ... ... ... except OtherException as e: ... ... ... else: ... ... ... finally: ... ... ... """), indent=4)) Module( body=[ Try( body=[ Expr( value=Constant(value=Ellipsis))], handlers=[ ExceptHandler( type=Name(id='Exception', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))]), ExceptHandler( type=Name(id='OtherException', ctx=Load()), name='e', body=[ Expr( value=Constant(value=Ellipsis))])], orelse=[ Expr( value=Constant(value=Ellipsis))], finalbody=[ Expr( value=Constant(value=Ellipsis))])], type_ignores=[])
- class ast.TryStar(body, handlers, orelse, finalbody)¶
tryблоки, за которыми следуют предложенияexcept*. Атрибуты те же, что и дляTry, ноExceptHandlerузлов вhandlersинтерпретируются какexcept*блоков, а не какexcept.>>> print(ast.dump(ast.parse(""" ... try: ... ... ... except* Exception: ... ... ... """), indent=4)) Module( body=[ TryStar( body=[ Expr( value=Constant(value=Ellipsis))], handlers=[ ExceptHandler( type=Name(id='Exception', ctx=Load()), body=[ Expr( value=Constant(value=Ellipsis))])], orelse=[], finalbody=[])], type_ignores=[])
- class ast.ExceptHandler(type, name, body)¶
Единственное предложение
except.type- это тип исключения, которому оно будет соответствовать, обычно это узелName(илиNoneдля универсального предложенияexcept:).name- это необработанная строка для имени, содержащего исключение, илиNone, если в предложении нетas foo.body- это список узлов.>>> print(ast.dump(ast.parse("""\ ... try: ... a + 1 ... except TypeError: ... pass ... """), indent=4)) Module( body=[ Try( body=[ Expr( value=BinOp( left=Name(id='a', ctx=Load()), op=Add(), right=Constant(value=1)))], handlers=[ ExceptHandler( type=Name(id='TypeError', ctx=Load()), body=[ Pass()])], orelse=[], finalbody=[])], type_ignores=[])
- class ast.With(items, body, type_comment)¶
Блок
with.items- это списокwithitemузлов, представляющих контекстные менеджеры, аbody- это блок с отступом внутри контекста.- type_comment¶
type_comment- это необязательная строка с типом аннотации в качестве комментария.
- class ast.withitem(context_expr, optional_vars)¶
Отдельный контекстный менеджер в блоке
with.context_expr- это контекстный менеджер, часто являющийся узломCall.optional_vars- этоName,TupleилиListдля частиas foo, илиNone, если она не используется.>>> print(ast.dump(ast.parse("""\ ... with a as b, c as d: ... something(b, d) ... """), indent=4)) Module( body=[ With( items=[ withitem( context_expr=Name(id='a', ctx=Load()), optional_vars=Name(id='b', ctx=Store())), withitem( context_expr=Name(id='c', ctx=Load()), optional_vars=Name(id='d', ctx=Store()))], body=[ Expr( value=Call( func=Name(id='something', ctx=Load()), args=[ Name(id='b', ctx=Load()), Name(id='d', ctx=Load())], keywords=[]))])], type_ignores=[])
Сопоставление с образцом¶
- class ast.Match(subject, cases)¶
Оператор
match.subjectсодержит объект сопоставления (объект, который сопоставляется с регистрами), аcasesсодержит итерацию изmatch_caseузлов с различными регистрами.
- class ast.match_case(pattern, guard, body)¶
Шаблон с одним регистром в операторе
match.patternсодержит шаблон соответствия, по которому будет сопоставляться объект. Обратите внимание, что узлыAST, созданные для шаблонов, отличаются от узлов, созданных для выражений, даже если они используют один и тот же синтаксис.Атрибут
guardсодержит выражение, которое будет вычислено, если шаблон соответствует объекту.bodyсодержит список узлов, которые должны выполняться, если шаблон совпадает и результат вычисления защитного выражения равен true.>>> print(ast.dump(ast.parse(""" ... match x: ... case [x] if x>0: ... ... ... case tuple(): ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchSequence( patterns=[ MatchAs(name='x')]), guard=Compare( left=Name(id='x', ctx=Load()), ops=[ Gt()], comparators=[ Constant(value=0)]), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchClass( cls=Name(id='tuple', ctx=Load()), patterns=[], kwd_attrs=[], kwd_patterns=[]), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.MatchValue(value)¶
Соответствующий литерал или шаблон значений, который сравнивается по равенству.
valueявляется узлом выражения. Допустимые узлы значений ограничены, как описано в документации к инструкции match. Этот шаблон выполняется успешно, если объект соответствия равен вычисленному значению.>>> print(ast.dump(ast.parse(""" ... match x: ... case "Relevant": ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchValue( value=Constant(value='Relevant')), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.MatchSingleton(value)¶
Шаблон совпадающего литерала, который сравнивается по идентификатору.
value- это синглтон, с которым нужно сравнить:None,True, илиFalse. Этот шаблон выполняется успешно, если объектом сопоставления является заданная константа.>>> print(ast.dump(ast.parse(""" ... match x: ... case None: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchSingleton(value=None), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.MatchSequence(patterns)¶
Шаблон соответствия последовательности.
patternsсодержит шаблоны, которые должны быть сопоставлены с элементами объекта, если объектом является последовательность. Соответствует последовательности переменной длины, если один из подшаблонов является узломMatchStar, в противном случае соответствует последовательности фиксированной длины.>>> print(ast.dump(ast.parse(""" ... match x: ... case [1, 2]: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchSequence( patterns=[ MatchValue( value=Constant(value=1)), MatchValue( value=Constant(value=2))]), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.MatchStar(name)¶
Соответствует остальной части последовательности в шаблоне соответствия последовательности переменной длины. Если
nameне равноNone, список, содержащий оставшиеся элементы последовательности, привязывается к этому имени, если общий шаблон последовательности выполнен успешно.>>> print(ast.dump(ast.parse(""" ... match x: ... case [1, 2, *rest]: ... ... ... case [*_]: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchSequence( patterns=[ MatchValue( value=Constant(value=1)), MatchValue( value=Constant(value=2)), MatchStar(name='rest')]), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchSequence( patterns=[ MatchStar()]), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.MatchMapping(keys, patterns, rest)¶
Шаблон сопоставления соответствия.
keys- это последовательность узлов выражения.patterns- это соответствующая последовательность узлов шаблона.rest- это необязательное имя, которое можно указать для отображения остальных элементов сопоставления. Разрешенные ключевые выражения ограничены, как описано в документации к инструкции match.Этот шаблон выполняется успешно, если объектом является отображение, все вычисленные ключевые выражения присутствуют в отображении, а значение, соответствующее каждому ключу, соответствует соответствующему подшаблону. Если
restне являетсяNone, то dict, содержащий остальные элементы сопоставления, привязывается к этому имени, если общий шаблон сопоставления выполнен успешно.>>> print(ast.dump(ast.parse(""" ... match x: ... case {1: _, 2: _}: ... ... ... case {**rest}: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchMapping( keys=[ Constant(value=1), Constant(value=2)], patterns=[ MatchAs(), MatchAs()]), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchMapping(keys=[], patterns=[], rest='rest'), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.MatchClass(cls, patterns, kwd_attrs, kwd_patterns)¶
Шаблон соответствия классу.
cls- это выражение, задающее номинальный класс, который должен быть сопоставлен.patterns- это последовательность узлов шаблона, которые должны быть сопоставлены с определенной классом последовательностью атрибутов соответствия шаблону.kwd_attrs- это последовательность дополнительные атрибуты, подлежащие сопоставлению (указанные в качестве аргументов ключевых слов в шаблоне класса),kwd_patternsявляются соответствующими шаблонами (указанными в качестве значений ключевых слов в шаблоне класса).Этот шаблон выполняется успешно, если объект является экземпляром указанного класса, все позиционные шаблоны соответствуют соответствующим атрибутам, определенным классом, и все указанные атрибуты ключевых слов соответствуют соответствующему шаблону.
Примечание: классы могут определять свойство, которое возвращает self, чтобы сопоставить узел шаблона с сопоставляемым экземпляром. Несколько встроенных типов также сопоставляются таким образом, как описано в документации по инструкции match.
>>> print(ast.dump(ast.parse(""" ... match x: ... case Point2D(0, 0): ... ... ... case Point3D(x=0, y=0, z=0): ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchClass( cls=Name(id='Point2D', ctx=Load()), patterns=[ MatchValue( value=Constant(value=0)), MatchValue( value=Constant(value=0))], kwd_attrs=[], kwd_patterns=[]), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchClass( cls=Name(id='Point3D', ctx=Load()), patterns=[], kwd_attrs=[ 'x', 'y', 'z'], kwd_patterns=[ MatchValue( value=Constant(value=0)), MatchValue( value=Constant(value=0)), MatchValue( value=Constant(value=0))]), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.MatchAs(pattern, name)¶
Соответствие «по шаблону», шаблону захвата или шаблону подстановки.
patternсодержит шаблон соответствия, по которому объект будет сопоставлен. Если шаблон равенNone, то узел представляет собой шаблон захвата (т.е. простое имя) и всегда будет успешным.Атрибут
nameсодержит имя, которое будет привязано в случае успешного выполнения шаблона. ЕслиnameравноNone,pattern, то также должно бытьNone, а узел представляет собой шаблон подстановки.>>> print(ast.dump(ast.parse(""" ... match x: ... case [x] as y: ... ... ... case _: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchAs( pattern=MatchSequence( patterns=[ MatchAs(name='x')]), name='y'), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchAs(), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
- class ast.MatchOr(patterns)¶
Сопоставление с «шаблоном or». Шаблон or по очереди сопоставляет каждый из своих подшаблонов с объектом, пока один из них не завершится успешно. Затем шаблон or считается успешным. Если ни один из подшаблонов не завершается успешно, шаблон or не выполняется. Атрибут
patternsсодержит список узлов шаблона соответствия, которые будут сопоставлены с объектом.>>> print(ast.dump(ast.parse(""" ... match x: ... case [x] | (y): ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchOr( patterns=[ MatchSequence( patterns=[ MatchAs(name='x')]), MatchAs(name='y')]), body=[ Expr( value=Constant(value=Ellipsis))])])], type_ignores=[])
Определения функций и классов¶
- class ast.FunctionDef(name, args, body, decorator_list, returns, type_comment)¶
Определение функции.
name- это необработанная строка имени функции.args- это узелarguments.body- это список узлов внутри функции.decorator_list- это список применяемых декораторов, который хранится самым первым (т.е. первый в списке будет применен последним).returns- это аннотация к возврату.
- type_comment¶
type_comment- это необязательная строка с типом аннотации в качестве комментария.
- class ast.Lambda(args, body)¶
lambda- это минимальное определение функции, которое можно использовать внутри выражения. В отличие отFunctionDef,bodyсодержит один узел.>>> print(ast.dump(ast.parse('lambda x,y: ...'), indent=4)) Module( body=[ Expr( value=Lambda( args=arguments( posonlyargs=[], args=[ arg(arg='x'), arg(arg='y')], kwonlyargs=[], kw_defaults=[], defaults=[]), body=Constant(value=Ellipsis)))], type_ignores=[])
- class ast.arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults, kwarg, defaults)¶
Аргументы для функции.
posonlyargs,argsиkwonlyargs- это спискиargузлов.varargиkwargявляются одиночнымиargузлами, ссылающимися на параметры*args, **kwargs.kw_defaults- это список значений по умолчанию для аргументов, содержащих только ключевые слова. Если значение равноNone, то требуется ввести соответствующий аргумент.defaults- это список значений по умолчанию для аргументов, которые могут передаваться позиционно. Если значений по умолчанию меньше, они соответствуют последним n аргументам.
- class ast.arg(arg, annotation, type_comment)¶
Единственный аргумент в списке.
arg- это необработанная строка имени аргумента;annotation- это его аннотация, например, узелName.- type_comment¶
type_comment- это необязательная строка с типом аннотации в качестве комментария
>>> print(ast.dump(ast.parse("""\ ... @decorator1 ... @decorator2 ... def f(a: 'annotation', b=1, c=2, *d, e, f=3, **g) -> 'return annotation': ... pass ... """), indent=4)) Module( body=[ FunctionDef( name='f', args=arguments( posonlyargs=[], args=[ arg( arg='a', annotation=Constant(value='annotation')), arg(arg='b'), arg(arg='c')], vararg=arg(arg='d'), kwonlyargs=[ arg(arg='e'), arg(arg='f')], kw_defaults=[ None, Constant(value=3)], kwarg=arg(arg='g'), defaults=[ Constant(value=1), Constant(value=2)]), body=[ Pass()], decorator_list=[ Name(id='decorator1', ctx=Load()), Name(id='decorator2', ctx=Load())], returns=Constant(value='return annotation'))], type_ignores=[])
- class ast.Return(value)¶
Оператор
return.>>> print(ast.dump(ast.parse('return 4'), indent=4)) Module( body=[ Return( value=Constant(value=4))], type_ignores=[])
- class ast.Yield(value)¶
- class ast.YieldFrom(value)¶
Выражение
yieldилиyield from. Поскольку это выражения, они должны быть заключены в узелExpr, если отправленное обратно значение не используется.>>> print(ast.dump(ast.parse('yield x'), indent=4)) Module( body=[ Expr( value=Yield( value=Name(id='x', ctx=Load())))], type_ignores=[]) >>> print(ast.dump(ast.parse('yield from x'), indent=4)) Module( body=[ Expr( value=YieldFrom( value=Name(id='x', ctx=Load())))], type_ignores=[])
- class ast.Global(names)¶
- class ast.Nonlocal(names)¶
Операторы
globalиnonlocal.names- это список необработанных строк.>>> print(ast.dump(ast.parse('global x,y,z'), indent=4)) Module( body=[ Global( names=[ 'x', 'y', 'z'])], type_ignores=[]) >>> print(ast.dump(ast.parse('nonlocal x,y,z'), indent=4)) Module( body=[ Nonlocal( names=[ 'x', 'y', 'z'])], type_ignores=[])
- class ast.ClassDef(name, bases, keywords, body, decorator_list)¶
Определение класса.
name- это необработанная строка для имени классаbases- это список узлов для явно указанных базовых классов.keywords- это список узловkeyword, в основном для «метакласса». В метакласс будут переданы другие ключевые слова, как указано в PEP-3115.body- это список узлов, представляющих код в определении класса.decorator_list- это список узлов, как вFunctionDef.
>>> print(ast.dump(ast.parse("""\ ... @decorator1 ... @decorator2 ... class Foo(base1, base2, metaclass=meta): ... pass ... """), indent=4)) Module( body=[ ClassDef( name='Foo', bases=[ Name(id='base1', ctx=Load()), Name(id='base2', ctx=Load())], keywords=[ keyword( arg='metaclass', value=Name(id='meta', ctx=Load()))], body=[ Pass()], decorator_list=[ Name(id='decorator1', ctx=Load()), Name(id='decorator2', ctx=Load())])], type_ignores=[])
Асинхронность и ожидание¶
- class ast.AsyncFunctionDef(name, args, body, decorator_list, returns, type_comment)¶
Определение функции
async def. Содержит те же поля, что иFunctionDef.
- class ast.Await(value)¶
Выражение
await.value- это то, чего оно ожидает. Допустимо только в теле выраженияAsyncFunctionDef.
>>> print(ast.dump(ast.parse("""\
... async def f():
... await other_func()
... """), indent=4))
Module(
body=[
AsyncFunctionDef(
name='f',
args=arguments(
posonlyargs=[],
args=[],
kwonlyargs=[],
kw_defaults=[],
defaults=[]),
body=[
Expr(
value=Await(
value=Call(
func=Name(id='other_func', ctx=Load()),
args=[],
keywords=[])))],
decorator_list=[])],
type_ignores=[])
- class ast.AsyncFor(target, iter, body, orelse, type_comment)¶
- class ast.AsyncWith(items, body, type_comment)¶
async forциклы иasync withконтекстные менеджеры. Они содержат те же поля, что иForиWithсоответственно. Допустимы только в телеAsyncFunctionDef.
Примечание
Когда строка анализируется с помощью ast.parse(), узлы оператора (подклассы ast.operator, ast.unaryop, ast.cmpop, ast.boolop и ast.expr_context) в возвращаемом дереве будут одиночными. Изменения в одном из них будут отражены во всех других случаях с таким же значением (например, ast.Add).
ast Помощники¶
Помимо классов узлов, модуль ast определяет эти служебные функции и классы для обхода абстрактных синтаксических деревьев:
- ast.parse(source, filename='<unknown>', mode='exec', *, type_comments=False, feature_version=None)¶
Преобразуем исходный код в AST-узел. Эквивалентно
compile(source, filename, mode, ast.PyCF_ONLY_AST).Если задано значение
type_comments=True, синтаксический анализатор модифицируется для проверки и возврата комментариев типа, как указано в PEP 484 и PEP 526. Это эквивалентно добавлениюast.PyCF_TYPE_COMMENTSк флагам, передаваемым вcompile(). При этом будут отображаться синтаксические ошибки в комментариях к неуместному типу. Без этого флага комментарии к типу будут игнорироваться, и полеtype_commentна выбранных узлах AST всегда будет иметь значениеNone. Кроме того, расположение комментариев# type: ignoreбудет возвращено как атрибутtype_ignoresдляModule(в противном случае это всегда будет пустой список).Кроме того, если
modeравно'func_type', синтаксис ввода изменяется, чтобы соответствовать PEP 484 «комментариям типа подписи», например(str, int) -> List[str].Установка
feature_versionдля кортежа(major, minor)приведет к попытке синтаксического анализа с использованием грамматики этой версии Python. Например, установкаfeature_version=(3, 9)приведет к попытке запретить синтаксический анализ операторовmatch. В настоящее времяmajorдолжно быть равно3. Самая низкая поддерживаемая версия -(3, 4)(и она может быть увеличена в будущих версиях Python); самая высокая -sys.version_info[0:2]. Попытка «с максимальными усилиями» означает, что нет никакой гарантии, что синтаксический анализ (или успех синтаксического анализа) будет таким же, как при запуске на версии Python, соответствующейfeature_version.Если исходный код содержит символ null, то возникает значение (
\0),ValueError.Предупреждение
Обратите внимание, что успешный разбор исходного кода в объект AST не гарантирует, что предоставленный исходный код является допустимым кодом на Python, который может быть выполнен на этапе компиляции, что может привести к дополнительным исключениям
SyntaxError. Например, исходный кодreturn 42генерирует допустимый AST-узел для инструкции return, но он не может быть скомпилирован сам по себе (он должен находиться внутри функционального узла).В частности,
ast.parse()не будет выполнять никаких проверок области видимости, которые выполняются на этапе компиляции.Предупреждение
Возможно аварийное завершение работы интерпретатора Python с достаточно большой/ сложной строкой из-за ограничений глубины стека в AST-компиляторе Python.
Изменено в версии 3.8: Добавлено
type_comments,mode='func_type'иfeature_version.
- ast.unparse(ast_obj)¶
Разберите объект
ast.ASTи сгенерируйте строку с кодом, который при обратном разборе с помощьюast.parse()создаст эквивалентный объектast.AST.Предупреждение
Созданная строка кода не обязательно будет равна исходному коду, который сгенерировал объект
ast.AST(без каких-либо оптимизаций компилятора, таких как постоянные кортежи/замороженные наборы).Предупреждение
Попытка разобрать очень сложное выражение приведет к появлению
RecursionError.Добавлено в версии 3.9.
- ast.literal_eval(node_or_string)¶
Вычислите узел выражения или строку, содержащую только литерал Python или отображение контейнера. Предоставленная строка или узел могут состоять только из следующих литеральных структур Python: строки, байты, числа, кортежи, списки, dicts, множества, логические значения,
NoneиEllipsis.Это может быть использовано для вычисления строк, содержащих значения Python, без необходимости разбора значений самостоятельно. Он не способен вычислять произвольно сложные выражения, например, с использованием операторов или индексации.
В прошлом эта функция была задокументирована как «безопасная», но не было указано, что это означает. Это вводило в заблуждение. Она специально разработана для того, чтобы не выполнять код на Python, в отличие от более общего
eval(). В нем нет пространства имен, нет поиска по имени или возможности вызова. Но он не защищен от атак: относительно небольшой ввод может привести к исчерпанию памяти или стека C, что приведет к сбою процесса. Также существует вероятность отказа в обслуживании при чрезмерном потреблении ресурсов процессора для некоторых входных данных. Поэтому не рекомендуется вызывать его для ненадежных данных.Предупреждение
Интерпретатор Python может привести к сбою из-за ограничений глубины стека в AST-компиляторе Python.
Это может привести к возникновению
ValueError,TypeError,SyntaxError,MemoryErrorиRecursionErrorв зависимости от неправильного ввода.Изменено в версии 3.2: Теперь разрешены байты и литералы set.
Изменено в версии 3.9: Теперь поддерживается создание пустых наборов с
'set()'.Изменено в версии 3.10: При вводе строк начальные пробелы и символы табуляции теперь убраны.
- ast.get_docstring(node, clean=True)¶
Вернуться строкой документации данного узел (который должен быть
FunctionDef,AsyncFunctionDef,ClassDef, илиModuleузел), илиNoneЕсли у него нет строкой документации. Если значение clean равно true, очистите отступы в строках документации с помощьюinspect.cleandoc().Изменено в версии 3.5:
AsyncFunctionDefтеперь поддерживается.
- ast.get_source_segment(source, node, *, padded=False)¶
Получите сегмент исходного кода источника, который сгенерировал узел. Если какая-то информация о местоположении (
lineno,end_lineno,col_offset, илиend_col_offset) отсутствует, вернитеNone.Если значение дополнено равно
True, то первая строка многострочного выражения будет дополнена пробелами, чтобы соответствовать ее исходному положению.Добавлено в версии 3.8.
- ast.fix_missing_locations(node)¶
Когда вы компилируете дерево узлов с
compile(), компилятор ожидает атрибутыlinenoиcol_offsetдля каждого узла, который их поддерживает. Заполнять это поле для сгенерированных узлов довольно утомительно, поэтому этот помощник добавляет эти атрибуты рекурсивно там, где они еще не установлены, устанавливая для них значения родительского узла. Это работает рекурсивно, начиная с node.
- ast.increment_lineno(node, n=1)¶
Увеличьте номер строки и номер конечной строки каждого узла в дереве, начиная с node, на n. Это полезно для «перемещения кода» в другое место в файле.
- ast.copy_location(new_node, old_node)¶
Скопируйте исходное местоположение (
lineno,col_offset,end_lineno, иend_col_offset) из old_node в new_node, если это возможно, и верните new_node.
- ast.iter_fields(node)¶
Выведите кортеж из
(fieldname, value)для каждого поля вnode._fields, которое присутствует в узле.
- ast.iter_child_nodes(node)¶
Возвращает все прямые дочерние узлы node, то есть все поля, которые являются узлами, и все элементы полей, которые являются списками узлов.
- ast.walk(node)¶
Рекурсивно возвращает все узлы-потомки в дереве, начиная с node (включая сам node), в произвольном порядке. Это полезно, если вы хотите изменить только узлы на месте и не заботитесь о контексте.
- class ast.NodeVisitor¶
Базовый класс посетителя узла, который просматривает абстрактное синтаксическое дерево и вызывает функцию посетителя для каждого найденного узла. Эта функция может возвращать значение, которое передается методом
visit().Этот класс предназначен для создания подкласса, в который добавляются методы visitor.
- visit(node)¶
Посетите узел. Реализация по умолчанию вызывает метод с именем
self.visit_classname, где classname - это имя класса узла, илиgeneric_visit(), если этот метод не существует.
- generic_visit(node)¶
Этот посетитель вызывает
visit()для всех дочерних узлов узла.Обратите внимание, что дочерние узлы узлов, у которых есть пользовательский метод visitor, не будут посещены, если посетитель не вызовет
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 и использовать возвращаемое значение методов visitor для замены или удаления старого узла. Если возвращаемое значение метода visitor равноNone, узел будет удален из своего местоположения, в противном случае он заменяется возвращаемым значением. Возвращаемое значение может быть исходным узлом, и в этом случае замена не производится.Вот пример преобразователя, который переписывает все случаи поиска имен (
foo) наdata['foo']:class RewriteName(NodeTransformer): def visit_Name(self, node): return Subscript( value=Name(id='data', ctx=Load()), slice=Constant(value=node.id), ctx=node.ctx )
Имейте в виду, что если узел, с которым вы работаете, имеет дочерние узлы, вы должны либо преобразовать дочерние узлы самостоятельно, либо сначала вызвать метод
generic_visit()для этого узла.Для узлов, которые были частью набора инструкций (это относится ко всем узлам инструкций), посетитель также может вернуть список узлов, а не только один узел.
Если
NodeTransformerвводит новые узлы (которые не были частью исходного дерева), не предоставляя им информацию о местоположении (например,lineno),fix_missing_locations()следует вызвать новое поддерево для пересчета информации о местоположении:tree = ast.parse('foo', mode='eval') new_tree = fix_missing_locations(RewriteName().visit(tree))
Обычно вы используете трансформатор следующим образом:
node = YourTransformer().visit(node)
- ast.dump(node, annotate_fields=True, include_attributes=False, *, indent=None)¶
Возвращает форматированный дамп дерева в node. В основном это полезно для целей отладки. Если значение annotate_fields равно true (по умолчанию), в возвращаемой строке будут отображаться имена и значения полей. Если значение annotate_fields равно false, результирующая строка будет более компактной за счет исключения однозначных имен полей. Такие атрибуты, как номера строк и смещения столбцов, по умолчанию не выводятся. Если это необходимо, для параметра include_attributes можно задать значение true.
Если indent является неотрицательным целым числом или строкой, то дерево будет напечатано с таким уровнем отступа. Уровень отступа, равный 0, отрицательный или
"", приведет только к вставке новых строк.None(по умолчанию) выбирает однострочное представление. При использовании целого положительного отступа на уровне задается количество пробелов. Если indent - это строка (например,"\t"), то эта строка используется для отступа на каждом уровне.Изменено в версии 3.9: Добавлена опция отступ.
Флаги компилятора¶
Следующие флаги могут быть переданы в compile(), чтобы изменить влияние на компиляцию программы:
- ast.PyCF_ALLOW_TOP_LEVEL_AWAIT¶
Обеспечивает поддержку верхнего уровня
await,async for,async withи асинхронного понимания.Добавлено в версии 3.8.
- ast.PyCF_ONLY_AST¶
Генерирует и возвращает абстрактное синтаксическое дерево вместо того, чтобы возвращать скомпилированный объект кода.
Использование командной строки¶
Добавлено в версии 3.9.
Модуль ast может быть запущен в виде скрипта из командной строки. Это так же просто, как:
python -m ast [-m <mode>] [-a] [infile]
Принимаются следующие варианты:
- -h, --help¶
Отобразите справочное сообщение и выйдите.
- -m <mode>¶
- --mode <mode>¶
Укажите, какой код должен быть скомпилирован, например, аргумент mode в
parse().
- --no-type-comments¶
Не разбирайте вводимые комментарии.
- -a, --include-attributes¶
Включите такие атрибуты, как номера строк и смещения столбцов.
Если указано значение infile, его содержимое автоматически обрабатывается и выводится в стандартный вывод. В противном случае содержимое считывается из стандартного ввода.
См.также
Green Tree Snakes, внешний ресурс документации, содержит подробные сведения о работе с Python AST.
ASTTokens аннотирует Python AST с указанием расположения токенов и текста в исходном коде, который их сгенерировал. Это полезно для инструментов, которые выполняют преобразования исходного кода.
leoAst.py объединяет представления программ на python на основе токенов и дерева синтаксического анализа, вставляя двусторонние ссылки между токенами и узлами ast.
LibCST анализирует код в виде конкретного синтаксического дерева, которое выглядит как ast-дерево и сохраняет все детали форматирования. Это полезно для создания приложений автоматического рефакторинга (code mod) и линтеров.
Parso - это синтаксический анализатор Python, который поддерживает восстановление после ошибок и повторный анализ для разных версий Python (в нескольких версиях Python). Person также может перечислить несколько синтаксических ошибок в вашем файле python.