ast --- درختهای سینتکس انتزاعی¶
کد منبع: Lib/ast.py
ماژول ast به برنامههای پایتون کمک میکند تا درختهای دستور زبان سینتکس انتزاعی پایتون را پردازش کنند. خود سینتکس انتزاعی ممکن است با هر انتشار پایتون تغییر کند؛ این ماژول به شما کمک میکند تا بهصورت برنامهای دریابید دستور زبان جاری چگونه است.
میتوان یک درخت سینتکس انتزاعی را با ارسال ast.PyCF_ONLY_AST بهعنوان پرچم به تابع توکار compile() یا با استفاده از تابع کمکی parse() ارائهشده در این ماژول، تولید کرد. نتیجه درختی از اشیاء خواهد بود که کلاسهای آن همگی از ast.AST ارثبری میکنند. میتوان یک درخت سینتکس انتزاعی را با استفاده از تابع توکار 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)
| Interpolation(expr value, constant str, int conversion, expr? format_spec)
| JoinedStr(expr* values)
| TemplateStr(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باشد. اگر ویژگیها بتوانند صفر یا بیشتر مقدار داشته باشند (با ستاره علامتگذاری شده باشند)، مقادیر بهصورت فهرستهای پایتون نمایش داده میشوند. هنگام کامپایل یک 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شمارههای خط اول و آخر بازهی متن منبع هستند (با اندیس ۱، بنابراین اولین خط، خط ۱ است) و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 این فیلد را نخواهد داشت. در پایتون 3.15، این وضعیت یک خطا پرتاب خواهد کرد.
تغییر یافته در نسخهی 3.8: اکنون از کلاس ast.Constant برای همهی ثابتها استفاده میشود.
تغییر یافته در نسخهی 3.9: اندیسهای ساده با مقدارشان نمایش داده میشوند، اسلایسهای گسترده (extended slices) بهصورت تاپلها نمایش داده میشوند.
تغییر یافته در نسخهی 3.13: سازندههای گره AST تغییر کردند تا پیشفرضهای معقولی برای فیلدهای از قلم افتاده فراهم کنند: اکنون مقدار پیشفرض فیلدهای اختیاری None است، مقدار پیشفرض فیلدهای فهرستی یک فهرست خالی است، و مقدار پیشفرض فیلدهایی از نوع ast.expr_context برابر Load() است. پیش از این، ویژگیهای از قلم افتاده در گرههای ساختهشده وجود نداشتند (دسترسی به آنها باعث پرتاب AttributeError میشد).
تغییر یافته در نسخهی 3.14: خروجی __repr__() گرههای AST شامل مقادیر فیلدهای گره است.
منسوخ شده از نسخهی 3.8، در نسخهی 3.14 حذف شده است: نسخههای پیشین پایتون، کلاسهای AST یعنی ast.Num، ast.Str، ast.Bytes، ast.NameConstant و ast.Ellipsis را فراهم میکردند که در پایتون 3.8 منسوخ شده بودند. این کلاسها در پایتون 3.14 حذف شدند و کارکرد آنها با ast.Constant جایگزین شده است.
منسوخ شده از نسخهی 3.9: کلاسهای قدیمی ast.Index و ast.ExtSlice هنوز در دسترس هستند، اما در نسخههای آینده پایتون حذف خواهند شد. تا آن زمان، نمونهسازی از آنها یک نمونه از کلاسی دیگر را برمیگرداند.
منسوخ شده از نسخهی 3.13, در نسخهی 3.15 حذف خواهد شد: نسخههای پیشین پایتون امکان ایجاد گرههای AST را که فاقد فیلدهای الزامی بودند، میدادند. بهطور مشابه، سازندههای گره AST اجازه میدادند آرگومانهای کلیدواژهای دلخواه بهعنوان ویژگیهای گره AST تنظیم شوند، حتی اگر با هیچیک از فیلدهای گره AST مطابقت نداشتند. این رفتار منسوخشده است و در پایتون 3.15 حذف خواهد شد.
توجه
توضیحات کلاسهای گره خاصی که در اینجا نمایش داده شدهاند، در ابتدا از پروژهی فوقالعادهی Green Tree Snakes و همهی مشارکتکنندگان آن اقتباس شدهاند.
گرههای ریشه¶
- class ast.Module(body, type_ignores)¶
یک ماژول پایتون، مانند ورودی پرونده. نوع گرهای که توسط
ast.parse()در حالت پیشفرض"exec"تولید میشود.bodyیکlistاز دستورها ماژول است.type_ignoresیکlistاز کامنتها نادیدهگرفتن نوع ماژول است؛ برای جزئیات بیشترast.parse()را ببینید.>>> print(ast.dump(ast.parse('x = 1'), indent=4)) Module( body=[ Assign( targets=[ Name(id='x', ctx=Store())], value=Constant(value=1))])
- class ast.Expression(body)¶
یک ورودی عبارت پایتون. نوع گرهای که توسط
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)¶
بازنماییای از کامنتهای نوع به سبک قدیمی برای توابع، زیرا نسخههای پایتون پیش از 3.5 از حاشیهنویسیهای PEP 484 پشتیبانی نمیکردند. نوع گره تولیدشده توسط
ast.parse()هنگامی که mode برابر"func_type"باشد.چنین کامنتهای نوعی به این شکل خواهند بود:
def sum_two_number(a, b): # type: (int, int) -> int return a + b
argtypesیک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, kind)¶
یک مقدار ثابت. ویژگی
valueدر لفظیConstantشامل شیء پایتونی بازنماییشده توسط آن است. مقادیر بازنماییشده میتوانند نمونههایی ازstr،bytes،int،float،complexوbool، و ثابتهایNoneوEllipsisباشند.ویژگی
kindیک رشته اختیاری است. برای مقادیر لفظی رشتهای با پیشوندu،kindروی'u'تنظیم میشود. برای همهی ثابتهای دیگر،kindبرابرNoneاست.>>> print(ast.dump(ast.parse('123', mode='eval'), indent=4)) Expression( body=Constant(value=123)) >>> print(ast.dump(ast.parse("u'hello'", mode='eval'), indent=4)) Expression( body=Constant(value='hello', kind='u'))
- class ast.FormattedValue(value, conversion, format_spec)¶
گرهای که نشاندهندهی یک فیلد قالببندی منفرد در یک افاسترینگ است. اگر رشته شامل یک فیلد قالببندی منفرد و هیچ چیز دیگری باشد، گره میتواند جداگانه باشد؛ در غیر این صورت در
JoinedStrظاهر میشود.valueهر گره عبارتی است (مانند یک لفظی، یک متغیر، یا یک فراخوانی تابع).conversionیک عدد صحیح است:format_specیک گرهJoinedStrاست که قالببندی مقدار را نشان میدهد، یا اگر قالبی مشخص نشده باشد،Noneاست. هر دوconversionوformat_specرا میتوان همزمان تنظیم کرد.
- class ast.JoinedStr(values)¶
یک افاسترینگ، شامل مجموعهای از گرههای
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.TemplateStr(values, /)¶
اضافه شده در نسخهی 3.14.
گرهای که یک لفظی رشتهی الگویی (template string literal) را نشان میدهد و شامل دنبالهای از گرههای
InterpolationوConstantاست. این گرهها میتوانند به هر ترتیبی باشند و نیازی نیست بهصورت یکدرمیان باشند.>>> expr = ast.parse('t"{name} finished {place:ordinal}"', mode='eval') >>> print(ast.dump(expr, indent=4)) Expression( body=TemplateStr( values=[ Interpolation( value=Name(id='name', ctx=Load()), str='name', conversion=-1), Constant(value=' finished '), Interpolation( value=Name(id='place', ctx=Load()), str='place', conversion=-1, format_spec=JoinedStr( values=[ Constant(value='ordinal')]))]))
- class ast.Interpolation(value, str, conversion, format_spec=None)¶
اضافه شده در نسخهی 3.14.
گرهای که نشاندهندهی یک فیلد درونیابی (interpolation field) در یک لفظی رشتهی الگو است.
valueمیتواند هر گرهی عبارت باشد (مانند یک لفظی، یک متغیر، یا یک فراخوانی تابع). این همان معنایFormattedValue.valueرا دارد.strیک ثابت است که حاوی متن عبارت درونیابی است.اگر
strرویNoneتنظیم شود، هنگام فراخوانیast.unparse()ازvalueبرای تولید کد استفاده میشود. در این حالت دیگر تضمین نمیشود که کد تولیدشده با کد اصلی یکسان باشد و این برای تولید کد در نظر گرفته شده است.conversionیک عدد صحیح است:-1: بدون تبدیل
۹۷ (
ord('a')): تبدیل!aبهASCII۱۱۴ (
ord('r')): تبدیل!rبهrepr()۱۱۵ (
ord('s')): تبدیلstringبا!s
این همان معنای
FormattedValue.conversionرا دارد.format_specیک گرهJoinedStrاست که قالببندی مقدار را نشان میدهد، یا اگر هیچ قالبی مشخص نشده باشد،Noneاست. میتوان هر دوconversionوformat_specرا همزمان تنظیم کرد. این همان معنایFormattedValue.format_specرا دارد.
- class ast.List(elts, ctx)¶
- class ast.Tuple(elts, ctx)¶
یک فهرست یا تاپل.
eltsشامل فهرستی از گرههای نشاندهنده عناصر است. اگر ظرف هدف انتساب باشد (یعنی(x,y)=something)،ctxStoreاست و در غیر این صورتLoadاست.>>> print(ast.dump(ast.parse('[1, 2, 3]', mode='eval'), indent=4)) Expression( body=List( elts=[ Constant(value=1), Constant(value=2), Constant(value=3)], ctx=Load())) >>> print(ast.dump(ast.parse('(1, 2, 3)', mode='eval'), indent=4)) Expression( body=Tuple( elts=[ Constant(value=1), Constant(value=2), Constant(value=3)], ctx=Load()))
- class ast.Set(elts)¶
یک مجموعه.
eltsشامل فهرستی از گرههایی است که عناصر مجموعه را نشان میدهند.>>> print(ast.dump(ast.parse('{1, 2, 3}', mode='eval'), indent=4)) Expression( body=Set( elts=[ Constant(value=1), Constant(value=2), Constant(value=3)]))
- class ast.Dict(keys, values)¶
یک دیکشنری.
keysوvaluesفهرستهایی از گرهها را نگه میدارند که بهترتیب نشاندهندهی کلیدها و مقدارها هستند و ترتیب آنها با یکدیگر مطابقت دارد (آنچه هنگام فراخوانیdictionary.keys()وdictionary.values()بازگردانده میشود).هنگام انجام واگشایی دیکشنری با استفاده از مقادیر لفظی دیکشنری، عبارت مورد واگشایی در فهرست
valuesقرار میگیرد و یکNoneدر موقعیت متناظر درkeysقرار میگیرد.>>> print(ast.dump(ast.parse('{"a":1, **d}', mode='eval'), indent=4)) Expression( body=Dict( keys=[ Constant(value='a'), None], values=[ Constant(value=1), Name(id='d', ctx=Load())]))
متغیرها¶
- class ast.Name(id, ctx)¶
نام یک متغیر.
idنام را بهعنوان یک رشته نگه میدارد، وctxیکی از انواع زیر است.
- class ast.Load¶
- class ast.Store¶
- class ast.Del¶
از ارجاعهای متغیر میتوان برای بارگذاری مقدار یک متغیر، انتساب مقدار جدید به آن، یا حذف آن استفاده کرد. به ارجاعهای متغیر یک زمینه داده میشود تا این حالتها از یکدیگر تشخیص داده شوند.
>>> print(ast.dump(ast.parse('a'), indent=4)) Module( body=[ Expr( value=Name(id='a', ctx=Load()))]) >>> print(ast.dump(ast.parse('a = 1'), indent=4)) Module( body=[ Assign( targets=[ Name(id='a', ctx=Store())], value=Constant(value=1))]) >>> print(ast.dump(ast.parse('del a'), indent=4)) Module( body=[ Delete( targets=[ Name(id='a', ctx=Del())])])
- class ast.Starred(value, ctx)¶
یک ارجاع به متغیر
*var.valueمتغیر را نگه میدارد، که معمولاً یک گرهNameاست. هنگام ساخت یک گرهCallبا*argsباید از این نوع استفاده شود.>>> print(ast.dump(ast.parse('a, *b = it'), indent=4)) Module( body=[ Assign( targets=[ Tuple( elts=[ Name(id='a', ctx=Store()), Starred( value=Name(id='b', ctx=Store()), ctx=Store())], ctx=Store())], value=Name(id='it', ctx=Load()))])
عبارات¶
- class ast.Expr(value)¶
هنگامی که یک عبارت، مانند فراخوانی تابع، بهتنهایی بهعنوان یک دستور ظاهر میشود و مقدار بازگشتی آن استفاده یا ذخیره نمیشود، در این ظرف قرار میگیرد.
valueیکی از گرههای دیگر در این بخش را نگه میدارد: یک گرهConstant، یک گرهName، یک گرهLambda، یک گرهYieldیا یک گرهYieldFrom.>>> print(ast.dump(ast.parse('-a'), indent=4)) Module( body=[ Expr( value=UnaryOp( op=USub(), operand=Name(id='a', ctx=Load())))])
- class ast.UnaryOp(op, operand)¶
یک عملیات یکعملوندی.
opعملگر است وoperandهر گرهی عبارت است.
- class ast.UAdd¶
- class ast.USub¶
- class ast.Not¶
- class ast.Invert¶
توکنهای عملگر یکعملوندی.
Notهمان کلیدواژهnotاست،Invertهمان عملگر~است.>>> print(ast.dump(ast.parse('not x', mode='eval'), indent=4)) Expression( body=UnaryOp( op=Not(), operand=Name(id='x', ctx=Load())))
- class ast.BinOp(left, op, right)¶
یک عملیات دودویی (مانند جمع یا تقسیم).
opعملگر است وleftوrightگرههای عبارت دلخواه هستند.>>> print(ast.dump(ast.parse('x + y', mode='eval'), indent=4)) Expression( body=BinOp( left=Name(id='x', ctx=Load()), op=Add(), right=Name(id='y', ctx=Load())))
- class ast.Add¶
- class ast.Sub¶
- class ast.Mult¶
- class ast.Div¶
- class ast.FloorDiv¶
- class ast.Mod¶
- class ast.Pow¶
- class ast.LShift¶
- class ast.RShift¶
- class ast.BitOr¶
- class ast.BitXor¶
- class ast.BitAnd¶
- class ast.MatMult¶
توکنهای عملگر دودویی.
- class ast.BoolOp(op, values)¶
یک عملیات بولی، 'or' یا 'and'.
opOrیا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است که آرگومانهای ارسالشده با کلیدواژه را نشان میدهند.
آرگومانهای
argsوkeywordsاختیاری هستند و پیشفرض آنها فهرستهای خالی است.>>> print(ast.dump(ast.parse('func(a, b=c, *d, **e)', mode='eval'), indent=4)) Expression( body=Call( func=Name(id='func', ctx=Load()), args=[ Name(id='a', ctx=Load()), Starred( value=Name(id='d', ctx=Load()), ctx=Load())], keywords=[ keyword( arg='b', value=Name(id='c', ctx=Load())), keyword( value=Name(id='e', ctx=Load()))]))
- class ast.keyword(arg, value)¶
یک آرگومان کلیدواژهای برای فراخوانی تابع یا تعریف کلاس.
argیک رشته خام از نام پارامتر است،valueیک گره برای ارسال است.
- class ast.IfExp(test, body, orelse)¶
یک عبارت مانند
a if b else c. هر فیلد یک گره را نگه میدارد، بنابراین در مثال زیر، هر سه، گرههایNameهستند.>>> print(ast.dump(ast.parse('a if b else c', mode='eval'), indent=4)) Expression( body=IfExp( test=Name(id='b', ctx=Load()), body=Name(id='a', ctx=Load()), orelse=Name(id='c', ctx=Load())))
- class ast.Attribute(value, attr, ctx)¶
دسترسی به ویژگی، مثلاً
d.keys.valueیک گره است، معمولاً یکName.attrیک رشتهی ساده است که نام ویژگی را مشخص میکند، وctxبسته به نوع عمل انجامشده روی ویژگی،Load،StoreیاDelاست.>>> print(ast.dump(ast.parse('snake.colour', mode='eval'), indent=4)) Expression( body=Attribute( value=Name(id='snake', ctx=Load()), attr='colour', ctx=Load()))
- class ast.NamedExpr(target, value)¶
یک عبارت نامدار. این گره AST توسط عملگر عبارت انتساب (که به عملگر walrus نیز شناخته میشود) تولید میشود. برخلاف گره
Assignکه در آن اولین آرگومان میتواند چندین گره باشد، در این حالت هر دوtargetوvalueباید گرههای تکی باشند.>>> print(ast.dump(ast.parse('(x := 4)', mode='eval'), indent=4)) Expression( body=NamedExpr( target=Name(id='x', ctx=Store()), value=Constant(value=4)))
اضافه شده در نسخهی 3.8.
زیرنویسگذاری¶
- class ast.Subscript(value, slice, ctx)¶
یک زیرنویس (subscript)، مانند
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نشان میدهد که یک درک ناهمگام است (به جایforازasync forاستفاده میکند). مقدار آن یک عدد صحیح (۰ یا ۱) است.>>> 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همیشه یا ۰ است (نشاندهندهی یک هدف «پیچیده») یا ۱ (نشاندهندهی یک هدف «ساده»). یک هدف «ساده» فقط شامل یک گره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) است،opAddاست، وvalueیکConstantبا مقدار ۱ است.ویژگی
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یک عدد صحیح است که سطح ایمپورت نسبی را نگه میدارد (۰ به معنای ایمپورت مطلق است).>>> 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)¶
یک الگوی case منفرد در یک دستور
match.patternشامل الگوی تطبیقی است که موضوع با آن تطبیق داده خواهد شد. توجه داشته باشید که گرههایASTتولیدشده برای الگوها با گرههای تولیدشده برای عبارات متفاوت هستند، حتی زمانی که سینتکس یکسانی دارند.ویژگی
guardشامل عبارتی است که اگر الگو با موضوع مطابقت داشته باشد، ارزیابی میشود.bodyشامل فهرستی از گرههاست که در صورتی اجرا میشوند که الگو مطابقت داشته باشد و نتیجه ارزیابی عبارت نگهبان درست باشد.>>> print(ast.dump(ast.parse(""" ... match x: ... case [x] if x>0: ... ... ... case tuple(): ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchSequence( patterns=[ MatchAs(name='x')]), guard=Compare( left=Name(id='x', ctx=Load()), ops=[ Gt()], comparators=[ Constant(value=0)]), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchClass( cls=Name(id='tuple', ctx=Load())), body=[ Expr( value=Constant(value=Ellipsis))])])])
اضافه شده در نسخهی 3.10.
- class ast.MatchValue(value)¶
یک لفظی تطبیق یا الگوی مقدار که بر اساس برابری مقایسه میکند.
valueیک گره عبارت است. گرههای مقدار مجاز، همانطور که در مستندات دستور تطبیق توضیح دادهشده است، محدود شدهاند. این الگو در صورتی موفق میشود که موضوع تطبیق با مقدار ارزیابیشده برابر باشد.>>> print(ast.dump(ast.parse(""" ... match x: ... case "Relevant": ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchValue( value=Constant(value='Relevant')), body=[ Expr( value=Constant(value=Ellipsis))])])])
اضافه شده در نسخهی 3.10.
- class ast.MatchSingleton(value)¶
یک الگوی تطبیق لفظی که بر اساس هویت مقایسه میکند.
valueتکنمونهای است که با آن مقایسه میشود:None،TrueیاFalse. این الگو در صورتی موفق میشود که موضوع تطبیق همان ثابت دادهشده باشد.>>> print(ast.dump(ast.parse(""" ... match x: ... case None: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchSingleton(value=None), body=[ Expr( value=Constant(value=Ellipsis))])])])
اضافه شده در نسخهی 3.10.
- class ast.MatchSequence(patterns)¶
یک الگوی تطبیق دنباله.
patternsشامل الگوهایی است که در صورت دنباله بودن موضوع، با عناصر موضوع تطبیق داده میشوند. اگر یکی از زیرالگوها یک گرهMatchStarباشد، با یک دنباله با طول متغیر تطبیق مییابد، در غیر این صورت با یک دنباله با طول ثابت تطبیق مییابد.>>> print(ast.dump(ast.parse(""" ... match x: ... case [1, 2]: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchSequence( patterns=[ MatchValue( value=Constant(value=1)), MatchValue( value=Constant(value=2))]), body=[ Expr( value=Constant(value=Ellipsis))])])])
اضافه شده در نسخهی 3.10.
- class ast.MatchStar(name)¶
بقیهی دنباله را در یک الگوی دنبالهی تطبیق با طول متغیر تطبیق میدهد. اگر
nameبرابرNoneنباشد، در صورت موفق بودن الگوی دنبالهی کلی، فهرستی حاوی عناصر باقیماندهی دنباله به آن نام مقید میشود.>>> print(ast.dump(ast.parse(""" ... match x: ... case [1, 2, *rest]: ... ... ... case [*_]: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchSequence( patterns=[ MatchValue( value=Constant(value=1)), MatchValue( value=Constant(value=2)), MatchStar(name='rest')]), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchSequence( patterns=[ MatchStar()]), body=[ Expr( value=Constant(value=Ellipsis))])])])
اضافه شده در نسخهی 3.10.
- class ast.MatchMapping(keys, patterns, rest)¶
یک الگوی نگاشت تطبیق.
keysدنبالهای از گرههای عبارت است.patternsدنبالهای متناظر از گرههای الگو است.restنامی اختیاری است که میتوان آن را برای گرفتن عناصر باقیماندهی نگاشت مشخص کرد. عبارات مجاز برای کلیدها، همانطور که در مستندات دستور match توضیح داده شده است، محدود شدهاند.این الگو زمانی موفق میشود که موضوع یک نگاشت باشد، همه عبارتهای کلید ارزیابیشده در نگاشت وجود داشته باشند، و مقدار متناظر با هر کلید با زیرالگوی متناظر مطابقت داشته باشد. اگر
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 را برمیگرداند تا یک گره الگو را با نمونهای که در حال تطبیق است، تطبیق دهند. چندین نوع توکار نیز به همین روش تطبیق داده میشوند، همانطور که در مستندات دستور 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))]), 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» (as-pattern) در تطبیق، یک الگوی ثبتکننده (capture pattern) یا یک الگوی wildcard (wildcard pattern).
patternشامل الگوی تطبیقی است که موضوع با آن تطبیق داده خواهد شد. اگر الگوNoneباشد، این گره بیانگر یک الگوی ثبتکننده (یعنی یک نام ساده) است و همیشه با موفقیت تطبیق داده خواهد شد.ویژگی
nameشامل نامی است که در صورت موفقیت الگو مقید خواهد شد. اگرnameبرابرNoneباشد،patternنیز بایدNoneباشد و گره نشاندهندهی الگوی وایلدکارد است.>>> print(ast.dump(ast.parse(""" ... match x: ... case [x] as y: ... ... ... case _: ... ... ... """), indent=4)) Module( body=[ Match( subject=Name(id='x', ctx=Load()), cases=[ match_case( pattern=MatchAs( pattern=MatchSequence( patterns=[ MatchAs(name='x')]), name='y'), body=[ Expr( value=Constant(value=Ellipsis))]), match_case( pattern=MatchAs(), body=[ Expr( value=Constant(value=Ellipsis))])])])
اضافه شده در نسخهی 3.10.
- class ast.MatchOr(patterns)¶
یک «الگوی یا» (or-pattern) در تطبیق. یک الگوی یا هر یک از الگوهای فرعی خود را بهنوبت با موضوع تطبیق میدهد، تا یکی موفق شود. سپس الگوی یا موفق تلقی میشود. اگر هیچکدام از الگوهای فرعی موفق نشوند، الگوی یا شکست میخورد. ویژگی
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حاشیهنویسی بازگشت (return annotation) است.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اگرoptimize <= 0باشدast.PyCF_ONLY_ASTو در غیر این صورت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برگردانده میشوند (در غیر این صورت همیشه یک فهرست خالی است).In addition, if
modeis'func_type', the input syntax is modified to correspond to PEP 484 "signature type comments", for example(str, int) -> List[str].تنظیم
feature_versionبه یک تاپل(major, minor)منجر به تلاش «بهترین تلاش» برای تجزیه با استفاده از دستور زبان آن نسخه از پایتون میشود. برای مثال، تنظیمfeature_version=(3, 9)تلاش میکند تجزیهی دستورهایmatchرا غیرمجاز کند. در حال حاضرmajorباید برابر با3باشد. کمترین نسخهی پشتیبانیشده(3, 7)است (و ممکن است در نسخههای آیندهی پایتون افزایش یابد)؛ بیشترین نسخهsys.version_info[0:2]است. تلاش «بهترین تلاش» به این معناست که تضمینی وجود ندارد که تجزیه (یا موفقیت تجزیه) همانند حالتی باشد که در نسخهی پایتون متناظر باfeature_versionاجرا میشود.اگر source حاوی یک نویسهی نال (
\0) باشد،ValueErrorپرتاب میشود.هشدار
توجه داشته باشید که تجزیهی موفقیتآمیز کد منبع به یک شیء AST تضمین نمیکند که کد منبع ارائهشده، کد پایتون معتبری باشد که بتواند اجرا شود، زیرا مرحلهی کامپایل میتواند استثناهای بیشتری از نوع
SyntaxErrorپرتاب کند. برای مثال، کد منبعreturn 42یک گره AST معتبر برای یک دستور return تولید میکند، اما نمیتواند بهتنهایی کامپایل شود (باید داخل یک گره تابع باشد).بهطور خاص،
ast.parse()هیچگونه بررسی محدودهای انجام نمیدهد، در حالی که مرحلهی کامپایل این کار را انجام میدهد.هشدار
ممکن است مفسر پایتون به دلیل محدودیتهای عمق پشته در کامپایلر AST پایتون، با رشتهای بهاندازه کافی بزرگ/پیچیده از کار بیفتد.
تغییر یافته در نسخهی 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را تولید کرده است برابر نخواهد بود (بدون هیچگونه بهینهسازی کامپایلر، مانند تاپلها/فروزنستهای ثابت).هشدار
تلاش برای بازگردانی (unparse) یک عبارت بسیار پیچیده منجر به
RecursionErrorمیشود.اضافه شده در نسخهی 3.9.
- ast.literal_eval(node_or_string)¶
یک گره عبارت یا رشتهای را که فقط شامل یک لفظی پایتون یا نمایش ظرف (container display) باشد، ارزیابی میکند. رشته یا گره ارائهشده فقط میتواند شامل ساختارهای لفظی پایتون زیر باشد: رشتهها، بایتها، اعداد، تاپلها، فهرستها، دیکشنریها، مجموعهها، بولیها،
NoneوEllipsis.میتوان از این برای ارزیابی رشتههای حاوی مقادیر پایتون استفاده کرد، بدون نیاز به اینکه خودتان مقادیر را تجزیه کنید. این مورد قادر به ارزیابی عبارتهای با پیچیدگی دلخواه نیست، برای مثال عبارتهایی که شامل عملگرها یا اندیسدهی باشند.
این تابع در گذشته بدون اینکه تعریف شود منظور از «امن» چیست، بهعنوان «امن» مستند شده بود. این موضوع گمراهکننده بود. این تابع بهطور خاص بهگونهای طراحی شده است که برخلاف
eval()که عمومیتر است، کد پایتون را اجرا نکند. هیچ فضای نامی وجود ندارد، هیچ جستوجوی نامی انجام نمیشود، و هیچ امکانی برای فراخوانی بیرونی وجود ندارد. اما این تابع از حملات مصون نیست: یک ورودی نسبتاً کوچک میتواند به اتمام حافظه یا اتمام پشته C منجر شود و فرایند را از کار بیندازد. همچنین امکان ایجاد منع سرویس ناشی از مصرف بیشازحد CPU در برخی ورودیها وجود دارد. بنابراین فراخوانی آن با دادههای غیرقابلاعتماد توصیه نمیشود.هشدار
ممکن است مفسر پایتون به دلیل محدودیتهای عمق پشته در کامپایلر AST پایتون از کار بیفتد.
ممکن است بسته به ورودی نامعتبر،
ValueError،TypeError،SyntaxError،MemoryErrorوRecursionErrorپرتاب شوند.تغییر یافته در نسخهی 3.2: اکنون مقادیر لفظی bytes و set را میپذیرد.
تغییر یافته در نسخهی 3.9: اکنون از ایجاد مجموعههای خالی با
'set()'پشتیبانی میشود.تغییر یافته در نسخهی 3.10: برای ورودیهای رشتهای، فاصلهها و تبهای ابتدایی اکنون حذف میشوند.
- ast.get_docstring(node, clean=True)¶
رشته مستندات مربوط به node دادهشده را برمیگرداند (که باید یک گره از نوع
FunctionDef،AsyncFunctionDef،ClassDefیاModuleباشد)، یا اگر رشته مستندات نداشته باشد،Noneرا برمیگرداند. اگر clean درست باشد، تورفتگی رشته مستندات را با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 را تولید (yield) میکند، یعنی تمام فیلدهایی که گره هستند و تمام آیتمهای فیلدهایی که فهرستهایی از گرهها هستند.
- ast.walk(node)¶
بهصورت بازگشتی تمام گرههای نواده در درختی که از node شروع میشود (از جمله خود node) را، بدون هیچ ترتیب مشخصی، تولید میکند. این در صورتی مفید است که فقط بخواهید گرهها را درجا تغییر دهید و به زمینه اهمیتی ندهید.
- class ast.NodeVisitor¶
یک کلاس پایهی بازدیدکنندهی گره که درخت سینتکس انتزاعی را پیمایش میکند و برای هر گرهی یافتشده، یک تابع بازدیدکننده را فراخوانی میکند. این تابع ممکن است مقداری برگرداند که توسط متد
visit()ارسال میشود.این کلاس برای زیرکلاسسازی در نظر گرفته شده است، بهطوری که زیرکلاس، متدهای بازدیدکننده (visitor) را اضافه میکند.
- visit(node)¶
از یک گره بازدید میکند. پیادهسازی پیشفرض، متدی به نام
self.visit_classnameرا فراخوانی میکند که در آن classname نام کلاس گره است، یا اگر آن متد وجود نداشته باشد،generic_visit()را فراخوانی میکند.
- generic_visit(node)¶
این بازدیدکننده،
visit()را روی تمام فرزندان گره فراخوانی میکند.توجه داشته باشید که گرههای فرزندِ گرههایی که یک متد بازدیدکننده سفارشی دارند، بازدید نخواهند شد، مگر اینکه بازدیدکننده
generic_visit()را فراخوانی کند یا خودش آنها را بازدید کند.
- visit_Constant(node)¶
تمام گرههای ثابت را مدیریت میکند.
اگر میخواهید در حین پیمایش تغییراتی را به گرهها اعمال کنید، از
NodeVisitorاستفاده نکنید. برای این منظور یک بازدیدکننده ویژه وجود دارد (NodeTransformer) که امکان اصلاح را فراهم میکند.منسوخ شده از نسخهی 3.8، در نسخهی 3.14 حذف شده است: متدهای
visit_Num()،visit_Str()،visit_Bytes()،visit_NameConstant()وvisit_Ellipsis()در Python 3.14+ فراخوانی نخواهند شد. برای مدیریت همه گرههای ثابت، در عوض متدvisit_Constant()را اضافه کنید.
- class ast.NodeTransformer¶
یک زیرکلاس از
NodeVisitorکه درخت سینتکس انتزاعی را پیمایش میکند و امکان تغییر گرهها را فراهم میکند.NodeTransformerدرخت سینتکس انتزاعی (AST) را پیمایش میکند و از مقدار بازگشتی متدهای بازدیدکننده برای جایگزینی یا حذف گره قدیمی استفاده میکند. اگر مقدار بازگشتی متد بازدیدکنندهNoneباشد، گره از موقعیت خود حذف میشود، در غیر این صورت با مقدار بازگشتی جایگزین میشود. ممکن است مقدار بازگشتی همان گره اصلی باشد که در این صورت هیچ جایگزینی انجام نمیشود.در اینجا یک تبدیلکننده (transformer) مثال آمده است که همهی موارد جستوجوی نام (
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))
معمولاً از تبدیلکننده (transformer) به این صورت استفاده میکنید:
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 یک عدد صحیح نامنفی یا رشته باشد، درخت با آن سطح تورفتگی بهصورت خوانا چاپ میشود. سطح تورفتگی ۰، منفی، یا
""فقط سطرهای جدید درج میکند.None(پیشفرض) نمایش تکسطری را انتخاب میکند. استفاده از تورفتگی عدد صحیح مثبت، در هر سطح به همان تعداد فاصله تورفتگی ایجاد میکند. اگر indent یک رشته باشد (مانند"\t")، از آن رشته برای تورفتگی هر سطح استفاده میشود.اگر show_empty نادرست باشد (حالت پیشفرض)، فهرستهای خالی اختیاری از خروجی حذف میشوند. مقادیر
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=[])
- ast.compare(a, b, /, *, compare_attributes=False)¶
دو AST را بهصورت بازگشتی مقایسه میکند.
compare_attributes بر اینکه آیا ویژگیهای AST در مقایسه در نظر گرفته شوند یا خیر، تأثیر میگذارد. اگر compare_attributes برابر
False(پیشفرض) باشد، ویژگیها نادیده گرفته میشوند. در غیر این صورت، همهی آنها باید برابر باشند. این گزینه برای بررسی اینکه آیا ASTها از نظر ساختاری برابرند اما در فضای سفید یا جزئیات مشابه تفاوت دارند، مفید است. ویژگیها شامل شمارهی سطرها و آفستهای ستونی هستند.اضافه شده در نسخهی 3.14.
پرچمهای کامپایلر¶
پرچمهای زیر را میتوان برای تغییر اثرات بر کامپایل یک برنامه به 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¶
نمایش پیام راهنما و خروج.
- --no-type-comments¶
کامنتهای نوع را تجزیه نکنید.
- -a, --include-attributes¶
شامل ویژگیهایی مانند شماره سطرها و آفستهای ستون (column offsets) باشد.
- --feature-version <version>¶
نسخه پایتون در قالب 3.x (برای مثال، 3.10). پیشفرض آن، نسخه فعلی مفسر است.
اضافه شده در نسخهی 3.14.
- -O <level>¶
- --optimize <level>¶
سطح بهینهسازی برای پارسر . بهطور پیشفرض بدون بهینهسازی است.
اضافه شده در نسخهی 3.14.
- --show-empty¶
نمایش فهرستهای خالی و فیلدهایی که
Noneهستند. بهطور پیشفرض، اشیاء خالی نمایش داده نمیشوند.اضافه شده در نسخهی 3.14.
اگر infile مشخص شده باشد، محتوای آن به AST تجزیه میشود و در stdout نوشته میشود. در غیر این صورت، محتوا از stdin خوانده میشود.
همچنین ملاحظه نمائید
Green Tree Snakes، یک منبع خارجی مستندات، جزئیات خوبی دربارهی کار با ASTهای پایتون دارد.
ASTTokens ASTهای پایتون را با موقعیتهای توکنها و متن در کد منبعی که آنها را تولید کرده است، حاشیهنویسی میکند. این موضوع برای ابزارهایی که تبدیلهایی روی کد منبع انجام میدهند، مفید است.
leoAst.py نمایشهای مبتنی بر توکن و مبتنی بر درخت تجزیه از برنامههای پایتون را با درج پیوندهای دوطرفه میان توکنها و گرههای AST یکپارچه میکند.
LibCST کد را بهصورت یک درخت سینتکس عینی (Concrete Syntax Tree) تجزیه میکند که شبیه به یک درخت ast است و تمام جزئیات قالببندی را حفظ میکند. این برای ساخت برنامههای بازسازی خودکار (codemod) و لینترها مفید است.
Parso یک پارسر پایتون است که از بازیابی خطا و تجزیهی رفتوبرگشتی برای نسخههای مختلف پایتون (در چندین نسخهی پایتون) پشتیبانی میکند. Parso همچنین میتواند چندین خطای سینتکسی را در پرونده پایتون شما فهرست کند.