ast --- 抽象语法树— Python 3.8.13 說明文件

文章推薦指數: 80 %
投票人數:10人

ast 模块帮助Python 程序处理Python 语法的抽象语法树。

抽象语法或许会随着Python 的更新发布而改变;该模块能够帮助理解当前语法在编程层面的样貌。

瀏覽 索引 模組| 下一頁| 上一頁| Python» 3.8.13Documentation» Python標準函式庫(StandardLibrary)» Python语言服务» | ast---抽象语法树¶ 源代码:Lib/ast.py ast模块帮助Python程序处理Python语法的抽象语法树。

抽象语法或许会随着Python的更新发布而改变;该模块能够帮助理解当前语法在编程层面的样貌。

抽象语法树可通过将ast.PyCF_ONLY_AST作为旗标传递给compile()内置函数来生成,或是使用此模块中提供的parse()辅助函数。

返回结果将是一个对象树,,其中的类都继承自ast.AST。

抽象语法树可被内置的compile()函数编译为一个Python代码对象。

节点类¶ classast.AST¶ 这是所有AST节点类的基类。

实际上,这些节点类派生自Parser/Python.asdl文件,其中定义的语法树示例如下。

它们在C语言模块_ast中定义,并被导出至ast模块。

抽象语法定义的每个左侧符号(比方说,ast.stmt或者ast.expr)定义了一个类。

另外,在抽象语法定义的右侧,对每一个构造器也定义了一个类;这些类继承自树左侧的类。

比如,ast.BinOp继承自ast.expr。

对于多分支产生式(也就是"和规则"),树右侧的类是抽象的;只有特定构造器结点的实例能被构造。

_fields¶ 每个具体类都有个属性_fields,用来给出所有子节点的名字。

每个具体类的实例对它每个子节点都有一个属性,对应类型如文法中所定义。

比如,ast.BinOp的实例有个属性left,类型是ast.expr. 如果这些属性在文法中标记为可选(使用问号),对应值可能会是None。

如果这些属性有零或多个(用星号标记),对应值会用Python的列表来表示。

所有可能的属性必须在用compile()编译得到AST时给出,且是有效的值。

lineno¶ col_offset¶ end_lineno¶ end_col_offset¶ Instancesofast.exprandast.stmtsubclasseshave lineno,col_offset,lineno,andcol_offset attributes.Thelinenoandend_linenoarethefirstand lastlinenumbersofsourcetextspan(1-indexedsothefirstlineisline1) andthecol_offsetandend_col_offsetarethecorresponding UTF-8byteoffsetsofthefirstandlasttokensthatgeneratedthenode. TheUTF-8offsetisrecordedbecausetheparserusesUTF-8internally. Notethattheendpositionsarenotrequiredbythecompilerandare thereforeoptional.Theendoffsetisafterthelastsymbol,forexample onecangetthesourcesegmentofaone-lineexpressionnodeusing source_line[node.col_offset:node.end_col_offset]. 一个类的构造器ast.T像下面这样parse它的参数。

如果有位置参数,它们必须和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版更變:Classast.Constantisnowusedforallconstants. 3.8版後已棄用:Oldclassesast.Num,ast.Str,ast.Bytes, ast.NameConstantandast.Ellipsisarestillavailable, buttheywillberemovedinfuturePythonreleases.Inthemeanwhile, instantiatingthemwillreturnaninstanceofadifferentclass. 抽象文法¶ 抽象文法目前定义如下 --ASDL's5builtintypesare: --identifier,int,string,object,constant modulePython { mod=Module(stmt*body,type_ignore*type_ignores) |Interactive(stmt*body) |Expression(exprbody) |FunctionType(expr*argtypes,exprreturns) --notreallyanactualnodebutusefulinJython'stypesystem. |Suite(stmt*body) stmt=FunctionDef(identifiername,argumentsargs, stmt*body,expr*decorator_list,expr?returns, string?type_comment) |AsyncFunctionDef(identifiername,argumentsargs, stmt*body,expr*decorator_list,expr?returns, string?type_comment) |ClassDef(identifiername, expr*bases, keyword*keywords, stmt*body, expr*decorator_list) |Return(expr?value) |Delete(expr*targets) |Assign(expr*targets,exprvalue,string?type_comment) |AugAssign(exprtarget,operatorop,exprvalue) --'simple'indicatesthatweannotatesimplenamewithoutparens |AnnAssign(exprtarget,exprannotation,expr?value,intsimple) --use'orelse'becauseelseisakeywordintargetlanguages |For(exprtarget,expriter,stmt*body,stmt*orelse,string?type_comment) |AsyncFor(exprtarget,expriter,stmt*body,stmt*orelse,string?type_comment) |While(exprtest,stmt*body,stmt*orelse) |If(exprtest,stmt*body,stmt*orelse) |With(withitem*items,stmt*body,string?type_comment) |AsyncWith(withitem*items,stmt*body,string?type_comment) |Raise(expr?exc,expr?cause) |Try(stmt*body,excepthandler*handlers,stmt*orelse,stmt*finalbody) |Assert(exprtest,expr?msg) |Import(alias*names) |ImportFrom(identifier?module,alias*names,int?level) |Global(identifier*names) |Nonlocal(identifier*names) |Expr(exprvalue) |Pass|Break|Continue --XXXJythonwillbedifferent --col_offsetisthebyteoffsetintheutf8stringtheparseruses attributes(intlineno,intcol_offset,int?end_lineno,int?end_col_offset) --BoolOp()canuseleft&right? expr=BoolOp(boolopop,expr*values) |NamedExpr(exprtarget,exprvalue) |BinOp(exprleft,operatorop,exprright) |UnaryOp(unaryopop,exproperand) |Lambda(argumentsargs,exprbody) |IfExp(exprtest,exprbody,exprorelse) |Dict(expr*keys,expr*values) |Set(expr*elts) |ListComp(exprelt,comprehension*generators) |SetComp(exprelt,comprehension*generators) |DictComp(exprkey,exprvalue,comprehension*generators) |GeneratorExp(exprelt,comprehension*generators) --thegrammarconstrainswhereyieldexpressionscanoccur |Await(exprvalue) |Yield(expr?value) |YieldFrom(exprvalue) --needsequencesforcomparetodistinguishbetween --x<4<3and(x<4)<3 |Compare(exprleft,cmpop*ops,expr*comparators) |Call(exprfunc,expr*args,keyword*keywords) |FormattedValue(exprvalue,int?conversion,expr?format_spec) |JoinedStr(expr*values) |Constant(constantvalue,string?kind) --thefollowingexpressioncanappearinassignmentcontext |Attribute(exprvalue,identifierattr,expr_contextctx) |Subscript(exprvalue,sliceslice,expr_contextctx) |Starred(exprvalue,expr_contextctx) |Name(identifierid,expr_contextctx) |List(expr*elts,expr_contextctx) |Tuple(expr*elts,expr_contextctx) --col_offsetisthebyteoffsetintheutf8stringtheparseruses attributes(intlineno,intcol_offset,int?end_lineno,int?end_col_offset) expr_context=Load|Store|Del|AugLoad|AugStore|Param slice=Slice(expr?lower,expr?upper,expr?step) |ExtSlice(slice*dims) |Index(exprvalue) 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=(exprtarget,expriter,expr*ifs,intis_async) excepthandler=ExceptHandler(expr?type,identifier?name,stmt*body) attributes(intlineno,intcol_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=(identifierarg,expr?annotation,string?type_comment) attributes(intlineno,intcol_offset,int?end_lineno,int?end_col_offset) --keywordargumentssuppliedtocall(NULLidentifierfor**kwargs) keyword=(identifier?arg,exprvalue) --importnamewithoptional'as'alias. alias=(identifiername,identifier?asname) withitem=(exprcontext_expr,expr?optional_vars) type_ignore=TypeIgnore(intlineno,stringtag) } ast中的辅助函数¶ 除了节点类,ast模块里为遍历抽象语法树定义了这些工具函数和类: ast.parse(source,filename='',mode='exec',*,type_comments=False,feature_version=None)¶ 把源码解析为AST节点。

和compile(source,filename,mode,ast.PyCF_ONLY_AST)等价。

Iftype_comments=Trueisgiven,theparserismodifiedtocheck andreturntypecommentsasspecifiedbyPEP484andPEP526. Thisisequivalenttoaddingast.PyCF_TYPE_COMMENTStothe flagspassedtocompile().Thiswillreportsyntaxerrors formisplacedtypecomments.Withoutthisflag,typecommentswill beignored,andthetype_commentfieldonselectedASTnodes willalwaysbeNone.Inaddition,thelocationsof#type: ignorecommentswillbereturnedasthetype_ignores attributeofModule(otherwiseitisalwaysanemptylist). Inaddition,ifmodeis'func_type',theinputsyntaxis modifiedtocorrespondtoPEP484"signaturetypecomments", e.g.(str,int)->List[str]. Also,settingfeature_versiontoatuple(major,minor) willattempttoparseusingthatPythonversion'sgrammar. Currentlymajormustequalto3.Forexample,setting feature_version=(3,4)willallowtheuseofasyncand awaitasvariablenames.Thelowestsupportedversionis (3,4);thehighestissys.version_info[0:2]. 警告 足够复杂或是巨大的字符串可能导致Python解释器的崩溃,因为Python的AST编译器是有栈深限制的。

3.8版更變:Addedtype_comments,mode='func_type'andfeature_version. ast.literal_eval(node_or_string)¶ 对表达式节点以及包含Python字面量或容器的字符串进行安全的求值。

传入的字符串或者节点里可能只包含下列的Python字面量结构:字符串,字节对象(bytes),数值,元组,列表,字典,集合,布尔值和None。

ThiscanbeusedforsafelyevaluatingstringscontainingPythonvaluesfrom untrustedsourceswithouttheneedtoparsethevaluesoneself.Itisnot capableofevaluatingarbitrarilycomplexexpressions,forexampleinvolving operatorsorindexing. 警告 足够复杂或是巨大的字符串可能导致Python解释器的崩溃,因为Python的AST编译器是有栈深限制的。

3.2版更變:目前支持字节和集合。

ast.get_docstring(node,clean=True)¶ Returnthedocstringofthegivennode(whichmustbea FunctionDef,AsyncFunctionDef,ClassDef, orModulenode),orNoneifithasnodocstring. Ifcleanistrue,cleanupthedocstring'sindentationwith inspect.cleandoc(). 3.5版更變:目前支持AsyncFunctionDef ast.get_source_segment(source,node,*,padded=False)¶ Getsourcecodesegmentofthesourcethatgeneratednode. Ifsomelocationinformation(lineno,end_lineno, col_offset,orend_col_offset)ismissing,returnNone. IfpaddedisTrue,thefirstlineofamulti-linestatementwill bepaddedwithspacestomatchitsoriginalposition. 3.8版新加入. ast.fix_missing_locations(node)¶ Whenyoucompileanodetreewithcompile(),thecompilerexpects linenoandcol_offsetattributesforeverynodethatsupports them.Thisisrathertedioustofillinforgeneratednodes,sothishelper addstheseattributesrecursivelywherenotalreadyset,bysettingthemto thevaluesoftheparentnode.Itworksrecursivelystartingatnode. ast.increment_lineno(node,n=1)¶ Incrementthelinenumberandendlinenumberofeachnodeinthetree startingatnodebyn.Thisisusefulto"movecode"toadifferent locationinafile. ast.copy_location(new_node,old_node)¶ Copysourcelocation(lineno,col_offset,end_lineno, andend_col_offset)fromold_nodetonew_nodeifpossible, andreturnnew_node. ast.iter_fields(node)¶ Yieldatupleof(fieldname,value)foreachfieldinnode._fields thatispresentonnode. ast.iter_child_nodes(node)¶ Yieldalldirectchildnodesofnode,thatis,allfieldsthatarenodes andallitemsoffieldsthatarelistsofnodes. ast.walk(node)¶ Recursivelyyieldalldescendantnodesinthetreestartingatnode (includingnodeitself),innospecifiedorder.Thisisusefulifyouonly wanttomodifynodesinplaceanddon'tcareaboutthecontext. classast.NodeVisitor¶ Anodevisitorbaseclassthatwalkstheabstractsyntaxtreeandcallsa visitorfunctionforeverynodefound.Thisfunctionmayreturnavalue whichisforwardedbythevisit()method. Thisclassismeanttobesubclassed,withthesubclassaddingvisitor methods. visit(node)¶ Visitanode.Thedefaultimplementationcallsthemethodcalled self.visit_classnamewhereclassnameisthenameofthenode class,orgeneric_visit()ifthatmethoddoesn'texist. generic_visit(node)¶ Thisvisitorcallsvisit()onallchildrenofthenode. Notethatchildnodesofnodesthathaveacustomvisitormethodwon'tbe visitedunlessthevisitorcallsgeneric_visit()orvisitsthem itself. Don'tusetheNodeVisitorifyouwanttoapplychangestonodes duringtraversal.Forthisaspecialvisitorexists (NodeTransformer)thatallowsmodifications. 3.8版後已棄用:Methodsvisit_Num(),visit_Str(),visit_Bytes(), visit_NameConstant()andvisit_Ellipsis()aredeprecated nowandwillnotbecalledinfuturePythonversions.Addthe visit_Constant()methodtohandleallconstantnodes. classast.NodeTransformer¶ 子类NodeVisitor用于遍历抽象语法树,并允许修改节点。

NodeTransformer将遍历抽象语法树并使用visitor方法的返回值去替换或移除旧节点。

如果visitor方法的返回值为None,则该节点将从其位置移除,否则将替换为返回值。

当返回值是原始节点时,无需替换。

如下是一个转换器示例,它将所有出现的名称(foo)重写为data['foo']: classRewriteName(NodeTransformer): defvisit_Name(self,node): returnSubscript( value=Name(id='data',ctx=Load()), slice=Index(value=Constant(value=node.id)), ctx=node.ctx ) 请记住,如果您正在操作的节点具有子节点,则必须先转换其子节点或为该节点调用generic_visit()方法。

对于属于语句集合(适用于所有语句节点)的节点,访问者还可以返回节点列表而不仅仅是单个节点。

IfNodeTransformerintroducesnewnodes(thatweren'tpartof originaltree)withoutgivingthemlocationinformation(suchas lineno),fix_missing_locations()shouldbecalledwith thenewsub-treetorecalculatethelocationinformation: 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)¶ Returnaformatteddumpofthetreeinnode.Thisismainlyusefulfor debuggingpurposes.Ifannotate_fieldsistrue(bydefault), thereturnedstringwillshowthenamesandthevaluesforfields. Ifannotate_fieldsisfalse,theresultstringwillbemorecompactby omittingunambiguousfieldnames.Attributessuchasline numbersandcolumnoffsetsarenotdumpedbydefault.Ifthisiswanted, include_attributescanbesettotrue. 也參考 GreenTreeSnakes,anexternal documentationresource,hasgooddetailsonworkingwithPythonASTs. ASTTokens annotatesPythonASTswiththepositionsoftokensandtextinthesource codethatgeneratedthem.Thisishelpfulfortoolsthatmakesourcecode transformations. leoAst.pyunifiesthe token-basedandparse-tree-basedviewsofpythonprogramsbyinserting two-waylinksbetweentokensandastnodes. LibCSTparsescodeasaConcreteSyntax Treethatlookslikeanasttreeandkeepsallformattingdetails.It's usefulforbuildingautomatedrefactoring(codemod)applicationsand linters. ParsoisaPythonparserthatsupports errorrecoveryandround-tripparsingfordifferentPythonversions(in multiplePythonversions).Parsoisalsoabletolistmultiplesyntaxerrors inyourpythonfile. 目录 ast---抽象语法树 节点类 抽象文法 ast中的辅助函数 上個主題 parser---访问Python解析树 下個主題 symtable——访问编译器的符号表 本頁 提交Bug 顯示原始碼 瀏覽 索引 模組| 下一頁| 上一頁| Python» 3.8.13Documentation» Python標準函式庫(StandardLibrary)» Python语言服务» |



請為這篇文章評分?