ast --- 抽象语法树— Python 3.8.13 說明文件
文章推薦指數: 80 %
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='
和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语言服务»
|
延伸文章資訊
- 1Python ast.NodeTransformer用法及代碼示例- 純淨天空
用法: class ast.NodeTransformer. NodeVisitor 子類遍曆抽象語法樹並允許修改節點。 NodeTransformer 將遍曆AST 並使用訪問者方法的返回值來...
- 2python ast 语法分析_怀瑜的博客
ast(Abstract Syntax Trees)是python中非常有用的一个模块,我们可以通过分析python的抽象语法树来对python的代码进行分析和修改。ast作用在python ...
- 3Python AST 抽象语法树 - 简书
因此ast给python源码检查、语法分析、修改代码以及代码调试等留下了足够的发挥空间。 1. AST简介. Python官方提供的CPython解释器对python源码的处理过程如下:. Pa...
- 4Python ast.AST用法及代碼示例- 純淨天空
用法: class ast.AST. 這是所有AST 節點類的基礎。實際的節點類派生自 Parser/Python.asdl 文件,該文件在下麵複製。它們在 _ast C 模塊中定義,並在 as...
- 5Python Ast介绍及应用 - 博客园
Ast是python源码到字节码的一种中间产物,借助ast模块可以从语法树的角度分析源码结构。此外,我们不仅可以修改和执行语法树,还可以将Source生成的语法树 ...