Matt laikus

Vegyünk egy kis “meta” – t a programozásról.

hogyan “tudja” a Python program(jobban tudja tolmácsként), hogyan kell futtatni a kódot?Ha még nem ismeri a programozást,úgy tűnhet, hogy magic.In tény, hogy még mindig varázslatnak tűnik számomra, miután több mint egy évtizede profi vagyok.

a Python tolmács nem varázslat(sajnálom, hogy csalódást okoztam).ez egy kiszámítható lépéskészletet követ, hogy lefordítsa a kódotaz utasításokba, amelyeket egy gép futtathat.

meglehetősen magas szinten a következő történik a kóddal:

  1. a kódot elemezzük (azaz felosztjuk) a darabok listájára, amelyet általában tokeneknek hívnak.Ezek a tokenek egy sor szabályon alapulnakolyan dolgokra, amelyeket másképp kell kezelni.Például a if kulcsszó más token, mint egy olyan numerikus érték, mint a 42.
  2. a tokenek nyers listája átalakulegy absztrakt Szintaxisfa, az AST felépítéséhez, amelyet ebben a bejegyzésben többet fogunk megvizsgálni.Az AST olyan csomópontok gyűjteménye, amelyek a Python nyelv nyelvtanán alapulnak.Ne aggódjon, ha ennek most nincs értelme, mivel pillanatnyilag jobban megvilágítjuk.
  3. egy absztrakt szintaxisfából a tolmács alacsonyabb szintű utasításformát hozhat létre,amelyet bájtkódnak neveznek.Ezek az utasítások olyan dolgok, mint a BINARY_ADD, és nagyon általánosak ahhoz, hogy egy számítógép futtassa őket.
  4. a rendelkezésre álló bytecode utasításokkal a tolmács végre futtathatja a kódot.A bájtkódot funkciók hívására használjákaz operációs rendszerben, amely végül kölcsönhatásba lép a CPU-val és a memóriávala program futtatásához.

sok további részlet beleférne ebbe a leírásba,de ez a durva vázlat arról, hogy a gépelt karaktereket hogyan hajtják végre a számítógépes CPU-k.

AST mint elemző eszköz

mire a forráskódod bytecode-vá változik, már túl késő ahhoz, hogy megértsd, amit írtál.Bytecode nagyon primitívés nagyon hangolt, hogy a tolmács fast.In más szavakkal, a bytecode az emberek feletti számítógépek számára készült.

másrészt az absztrakt szintaxisfáknak elegendő strukturált információjuk van bennükhogy hasznosak legyeneka kód megismeréséhez.Az ASTs még mindig nem túl emberbarát, de ésszerűbb, mint a bájtkód ábrázolása.

mivel a Python egy” batteries included ” nyelv,az ASTs használatához szükséges eszközök be vannak építve a standard könyvtárba.

az AST-kkel való munka elsődleges eszköze a ast modul.Nézzünk meg egy példát, hogy lássuk, hogyan működik ez.

AST példa szerint

Az alábbiakban a példa Python szkriptet fogjuk használni.Ez a szkript válaszol arra a kérdésre, hogy”milyen modulokat importáltak?”

import astfrom pprint import pprint

def main():with open("ast_example.py", "r") as source:tree = ast.parse(source.read())

analyzer <span style="color:#f92672">=</span> Analyzer()analyzer<span style="color:#f92672">.</span>visit(tree)analyzer<span style="color:#f92672">.</span>report()

class Analyzer(ast.NodeVisitor):def init(self):self.stats = {“import”: , “from”: }

<span style="color:#66d9ef">def</span> <span style="color:#a6e22e">visit_Import</span>(self, node): <span style="color:#66d9ef">for</span> alias <span style="color:#f92672">in</span> node<span style="color:#f92672">.</span>names: self<span style="color:#f92672">.</span>stats<span style="color:#f92672">.</span>append(alias<span style="color:#f92672">.</span>name) self<span style="color:#f92672">.</span>generic_visit(node)<span style="color:#66d9ef">def</span> <span style="color:#a6e22e">visit_ImportFrom</span>(self, node): <span style="color:#66d9ef">for</span> alias <span style="color:#f92672">in</span> node<span style="color:#f92672">.</span>names: self<span style="color:#f92672">.</span>stats<span style="color:#f92672">.</span>append(alias<span style="color:#f92672">.</span>name) self<span style="color:#f92672">.</span>generic_visit(node)<span style="color:#66d9ef">def</span> <span style="color:#a6e22e">report</span>(self): pprint(self<span style="color:#f92672">.</span>stats)

if name == “main”:main()

Ez a kód néhány fontos dolgot csinál:

  1. egy Python fájl szövegét(ebben az esetben magát a példakódot)absztrakt szintaxisfává alakítja.
  2. elemzi az AST-t, hogy kivonjon belőle néhány információt.

ezt a kódot a következőképpen futtathatja:

$ python3 ast_example.py{'from': , 'import': }

átalakítás AST

with open("ast_example.py", "r") as source: tree = ast.parse(source.read())

két kódsorban olvasunk egy fájlt,és létrehozunk egy treenevű AST-t.A ast.parse funkció teszi ezt egy pillanat alatt!Ennek a funkciónak a motorháztetője alatt rengeteg történik, amit boldogan figyelmen kívül hagyhatunk.

egy függvényhívással a Python feldolgozta az összes tokent, követte a nyelv összes szabályát, és felépített egy adatstruktúrát (pl., egy fa), amely tartalmazza az összes releváns információta kód futtatásához.

mielőtt továbblépnénk,Vegyünk egy pillanatra, hogy fontolja meg, mi a fa.A fák nagyon mély topicin szoftverfejlesztésígy ezt elsődlegesnek, nem pedig kimerítő magyarázatnak tekinti.

a fa az adatok tárolásának módjamint az “élek” által összekapcsolt “csomópontok” halmaza.”

 +-----+ | A | +-----+ / \ / \+-----+ +-----+| B | | C |+-----+ +-----+

ebben a diagramban az A,B és C mind csomópontokés vannak élek, amelyek a-T B-hez és A-T C-hez kötik.

ennek a fának a kódban való ábrázolásának egyik módja lehet:

class Node: def __init__(self, value): self.value = value self.children = tree = Node('A')tree.children.append(Node('B'))tree.children.append(Node('C'))

figyeljük meg, hogy a tree valójában egy csomópont!Amikor egy fával dolgozunk, valójában csomópontok gyűjteményével foglalkozunk, és a fa változó hivatkozás a “gyökér” csomópontra(pl. a csomópont).ilyen struktúrával ellenőrizhetjük a fa minden csomópontjátés cselekedjünk.Ezt úgy tesszük, hogy meglátogatjuk a fa minden csomópontjátés feldolgozzuk az adatait.

def print_node_value(value): print(value)def visit(node, handle_node): handle_node(node.value) for child in node.children: visit(child, handle_node)# tree is from the previous example.visit(tree, print_node_value)# This should print:# A# B# C

most,hogy van egy elképzelésünk arról, hogy mi a fa, megfontolhatjuk, hogy mit csinál a példa szkript következő szakasza.A Python absztrakt szintaxisfa faszerkezete jobban érintett a csomópontok száma és a tárolt adatok típusa miatt, mégis a csomópontok és az élek alapgondolata ugyanaz.

elemezze az AST-t

Miután megvan a fa,a Analyzer követi a látogatói mintát, amelyet fent mutattamaz információ kinyerésére a fáról.

megjegyeztem, hogy a Python AST bonyolultabb, mint az alapvető Node tervezés.Az egyik különbség az, hogy különböző típusú csomópontokat követ.Itt hasznos aast.NodeVisitor.

a NodeVisitor bármilyen típusú csomópontra válaszolhat a Pythonban AST.To látogasson el egy adott típusú csomópontra, meg kell valósítanunk egy módszertamely úgy néz ki, mint visit_<node type>.

a példakódom megpróbálja kideríteni imports.To tudjon meg többet az importálásról, a kód a Import és ImportFrom csomóponttípusokból származik.

def visit_Import(self, node): for alias in node.names: self.stats.append(alias.name) self.generic_visit(node)def visit_ImportFrom(self, node): for alias in node.names: self.stats.append(alias.name) self.generic_visit(node)

Ez a kód a modul nevét veszi felés a statisztikák listájában tárolja.Bár a kód nem divatos, megmutatja, hogyan kell kölcsönhatásba lépniaz AST csomópontokkal.

aNodeVisitor osztály definiálásával felhasználhatjuk a fa elemzésére.

analyzer = Analyzer()analyzer.visit(tree)

a visit a módszer a visit_<node type> metódust delegálja a visit_<node type> találkozottmiközben áthalad a fa szerkezetén.

szóval, milyen típusú csomópont típusok vannak?A teljes listát a ast modul dokumentációjában találhatja meg.Őszintén szólva, ezt a dokumentációt kissé nehéz felszívni.Lehet, hogy több sikerrel jár, ha egy kimerítőbb útmutatóra hivatkozik, mint például a zöld fa kígyók csomópontok útmutatója.

A

becsomagolása mostanra remélhetőleg megérti, hogyan kell:

  1. építsen egy AST-t a Python forráskódjából.
  2. végezzen elemzést az AST-n NodeVisitor használatával.

azt hiszem, sok érdekes kérdésre válaszolhata kódodrólelvont szintaxisfák használatával.Kérdések, mint:

  • hány változót használtam?
  • melyek a leggyakoribb függvényhívások a kódomban?
  • a moduljaim szorosan kapcsolódnak egymáshoz?
  • mely harmadik fél könyvtárai jelennek meg gyakran a különböző csomagokban?

a ast modul valószínűleg nem olyan eszköz, amelyet nagyon often.In azokban az időkben, amikor szüksége van ast, minimális API-ja meglehetősen emlékezetesés gyorsan elemezheti a kódot.

ha hasznosnak találta ezt, megosztaná ezt a Twitter-Envagy a kedvenc közösségi média webhelyén?Szeretek beszélgetni az emberekkel az ilyen témákrólígy nyugodtan tweetelj nekem a@mblayman oldalon.

tudj meg többet a Pythonról!

csatlakozhat a hírlevelemhez több mint 1000 fejlesztővel együtt, hogy segítsen többet megtudni a Django – ról és a Pythonról.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.