Python je úžasný.
Prekvapivo je to dosť nejednoznačné vyhlásenie. Čo mám na mysli pod pojmom „Python“? Mám tým na mysli Python abstrakt rozhranie ? Mám na mysli CPython, spoločný Python implementácia (a nemýliť si s podobne pomenovaným Cythonom)? Alebo mám na mysli úplne niečo iné? Možno mám skryto na mysli Jython alebo IronPython alebo PyPy. Alebo som sa naozaj dostal do hlbokého konca a hovorím o RPython alebo RubyPython (čo sú veľmi, veľmi odlišné veci).
Zatiaľ čo vyššie spomínané technológie sa bežne nazývajú a bežne sa na ne odkazuje, niektoré z nich slúžia úplne iným účelom (alebo fungujú aspoň úplne inak).
Počas svojej práce s rozhraniami Pythonu som narazil na kopu týchto nástrojov. * Ython. Ale až donedávna som si našiel čas na to, aby pochopil, čo sú zač, ako pracujú a prečo sú nevyhnutné (svojimi vlastnými spôsobmi).
V tomto tutoriále začnem úplne od začiatku a prejdem rôznymi implementáciami Pythonu až po dôkladné predstavenie jazyka PyPy, ktorý je podľa mňa budúcnosťou jazyka.
Všetko sa začína pochopením toho, čo vlastne „Python“ je.
Ak dobre rozumiete strojovému kódu, virtuálnym strojom a podobne, neváhajte preskočiť vpred .
Toto je spoločný bod zmätok pre začiatočníkov v Pythone .
Prvá vec, ktorú si treba uvedomiť pri porovnávaní, je, že „Python“ je rozhranie . Existuje špecifikácia toho, čo Python by mal robiť a ako to by mal správať (ako pri každom rozhraní). A je ich viac implementácie (ako pri každom rozhraní).
Druhá vec, ktorú si treba uvedomiť, je, že „interpretované“ a „zostavené“ sú vlastnosťami súboru implementácia , nie rozhranie .
Samotná otázka teda nie je skutočne dobre sformulovaná.
Je Python interpretovaný alebo kompilovaný? Otázka nie je skutočne dobre formovaná.To znamená, že pri najbežnejšej implementácii Pythonu (CPython: napísaný v jazyku C, často označovaný ako jednoducho „Python“, a čo určite používate, ak nemáte tušenie, o čom hovorím), je odpoveď: vykladané , s niektoré kompilácia. CPython zostavuje * Zdrojový kód Pythonu do bytecode, a potom tlmočí tento bajtkód, vykonávajúci ho za chodu.
* Poznámka: nejde o „kompiláciu“ v tradičnom zmysle slova. Spravidla by sme povedali, že kompilácia vyžaduje jazyk na vysokej úrovni a prevedie ho na strojový kód. Ale je to niečo ako ‚kompilácia‘.
Pozrime sa na túto odpoveď podrobnejšie, pretože nám pomôže pochopiť niektoré koncepty, ktoré sa v príspevku objavia neskôr.
Je veľmi dôležité pochopiť rozdiel medzi bajtovým kódom a strojovým kódom (al. Natívnym kódom), ktorý možno najlepšie ilustruje príklad:
Veľmi stručne: strojový kód je oveľa rýchlejší, ale bytecode je prenosnejší a bezpečnejší .
Strojový kód vyzerá inak v závislosti od vášho stroja, ale bajtkód vyzerá rovnako na všetkých strojoch. Dalo by sa povedať, že strojový kód je optimalizované k vášmu nastaveniu.
Vrátime sa k implementácii CPython a proces reťazca nástrojov je nasledovný:
Ako som už spomínal, Python má niekoľko implementácie. Ako už bolo spomenuté skôr, najbežnejším je opäť CPython, ale pre účely tohto sprievodcu porovnaním je potrebné spomenúť aj ďalšie. Toto bola implementácia Pythonu napísaná v jazyku C a považovala sa za „predvolenú“ implementáciu.
Ale čo alternatívne implementácie Pythonu? Jedným z výraznejších je Jython , napísaná Java implementácia Pythonu, ktorá využíva JVM. Zatiaľ čo CPython produkuje bytecode na spustenie na CPython VM, Jython produkuje Bajtový kód Java bežať na JVM (to je to isté, čo sa vyrába pri kompilácii programu Java).
„Prečo by ste niekedy používali alternatívnu implementáciu?“, Môžete sa opýtať. No, pre jedného, tieto rôzne implementácie Pythonu sa pekne hrajú s rôznymi zásobníkmi technológií .
Vďaka CPython je veľmi ľahké písať prípony C pre váš kód Pythonu, pretože ich nakoniec vykoná tlmočník C. Na druhej strane Jython uľahčuje prácu s ostatnými programami Java: môžete importovať akýkoľvek Triedy Java bez ďalšieho úsilia, vyvolávanie a využívanie vašich tried Java z vašich programov Jython. (Okrem: ak ste sa nad tým bližšie nezamýšľali, je to vlastne orechové. Sme v bode, v ktorom môžete kombinovať a miešať rôzne jazyky a všetky ich kompilovať do rovnakej látky. (Ako už spomenul Rostin , programy, ktoré kombinujú Fortran a C kód, existujú už nejaký čas. To samozrejme nie je nevyhnutne nové. Ale stále je to v pohode.))
Ako príklad možno uviesť platný kód Jython:
[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_51 >>> from java.util import HashSet >>> s = HashSet(5) >>> s.add('Foo') >>> s.add('Bar') >>> s [Foo, Bar]
IronPython je ďalšia populárna implementácia Pythonu, napísaná celá v jazyku C # a zameraná na zásobník .NET. Najmä beží na tom, čo by ste mohli nazvať .NET Virtual Machine, Microsoft Common Language Runtime (CLR) porovnateľné s JVM.
Možno si poviete Jython: Java :: IronPython: C # . Bežia na rovnakých príslušných virtuálnych počítačoch, môžete importovať triedy C # z kódu IronPython a triedy Java z kódu Jython atď.
Je úplne možné prežiť bez toho, aby ste sa dotkli implementácie iného ako CPython Python. Existujú však výhody, ktoré môžete mať pri prechode na iný server, z ktorých väčšina závisí od vášho technologického radu. Používate veľa jazykov založených na JVM? Jython môže byť pre vás. Všetko o .NET zásobníku? Možno by ste mali vyskúšať program IronPython (a možno už máte).
Mimochodom: zatiaľ by to nebolo dôvod Ak chcete použiť inú implementáciu, nezabudnite, že tieto implementácie sa skutočne líšia v správaní okrem toho, ako zaobchádzajú s vašim zdrojovým kódom Python. Tieto rozdiely sú však zvyčajne malé a časom sa rozpúšťajú alebo objavujú, pretože tieto implementácie sa vyvíjajú aktívne. Napríklad IronPython štandardne používa reťazce Unicode ; CPython však predvolené nastavenie je ASCII pre verzie 2.x (zlyhanie s UnicodeEncodeError pre znaky iné ako ASCII), ale podporuje Reťazce Unicode v predvolenom nastavení pre 3.x .
Takže máme implementáciu Pythonu napísanú v jazyku C, jednu v Jave a jednu v C #. Ďalším logickým krokom: implementácia Pythonu napísaná v ... Python . (Vzdelaný čitateľ si všimne, že je to mierne zavádzajúce.)
Tu by mohli byť veci mätúce. Po prvé, poďme diskutovať o kompilácii just-in-time (JIT).
Pripomeňme, že natívny strojový kód je oveľa rýchlejší ako bytecode. Čo by sa stalo, keby sme mohli zostaviť časť nášho bajtkódu a potom ho spustiť ako natívny kód? Za zostavenie bytecode (tj. Čas) by sme museli zaplatiť určitú cenu, ale ak by bol konečný výsledok rýchlejší, bolo by to skvelé! To je motivácia kompilácie JIT, hybridnej techniky, ktorá kombinuje výhody tlmočníkov a prekladateľov. V základných pojmoch chce JIT využiť kompiláciu na urýchlenie interpretovaného systému.
Napríklad spoločný prístup JIT:
O tom je implementácia PyPy: zavedenie JIT do Pythonu (pozri Dodatok za predchádzajúce úsilie). Existujú samozrejme aj ďalšie ciele: Cieľom PyPy je byť multiplatformový, pamäťovo nenáročný a bez stohovania. Ale JIT je skutočne jeho predajná stránka. Ako priemer za veľa časových testov sa hovorí, že zvyšuje výkon faktorom 6,27 . Rozpis nájdete v tejto tabuľke z Centrum rýchlosti PyPy :
PyPy má obrovský potenciál a v tomto okamihu je vysoko kompatibilný s CPython (tzv môže bežať Flask, Django , atď.).
Okolo PyPy je ale veľa zmätku (pozri napríklad tento nezmyselný návrh na vytvorenie PyPyPy… ). Podľa môjho názoru je to predovšetkým preto, že PyPy sú vlastne dve veci:
Tlmočník jazyka Python napísaný v jazyku RPython (nie Python (predtým som klamal)). RPython je podmnožina Pythonu so statickým písaním. V Pythone je „Väčšinou nemožné“ dôsledne uvažovať o typoch (Prečo je to také ťažké? Zvážte skutočnosť, že:
x = random.choice([1, 'foo'])
by bol platný kód Pythonu (kredit pre Gesto ). Aký je typ x
? Ako môžeme uvažovať o typoch premenných, keď typy nie sú ani striktne vynútené?). S RPython obetujete určitú flexibilitu, ale namiesto toho je oveľa, oveľa jednoduchšie uvažovať o správe pamäte a ktovie čo ešte, čo umožňuje optimalizáciu.
Kompilátor, ktorý kompiluje kód RPython pre rôzne ciele a pridáva do JIT. Predvolená platforma je C, t. J. Kompilátor RPython-to-C, ale môžete zacieliť aj na JVM a ďalšie.
Pre lepšiu prehľadnosť v tomto sprievodcovi porovnaním Pythonu budem na ne odkazovať ako PyPy (1) a PyPy (2).
Prečo by ste potrebovali tieto dve veci a prečo pod rovnakou strechou? Popremýšľajte o tom takto: PyPy (1) je tlmočník napísaný v RPythone. Takže vezme užívateľský kód v jazyku Python a skompiluje ho na bajtkód. Samotný tlmočník (napísaný v RPythone) musí byť interpretovaný inou implementáciou Pythonu, aby mohol bežať, však?
No, mohli by sme použite CPython viesť tlmočníka. Ale to by nebolo veľmi rýchle.
Namiesto toho ide o to, že používame PyPy (2) (označované ako RPython Toolchain) na kompiláciu PyPyho tlmočníka až po kód pre inú platformu (napr. C, JVM alebo CLI), ktorý bude bežať na našom stroji, a pridáme do JIT ako dobre. Je to čarovné: PyPy dynamicky pridáva JIT k tlmočníkovi a generuje vlastný kompilátor! ( Toto je opäť orechové: zostavujeme tlmočníka a pridáme ďalší samostatný samostatný kompilátor. )
Výsledkom je samostatný spustiteľný súbor, ktorý interpretuje zdrojový kód Pythonu a využíva optimalizácie JIT. Čo sme práve chceli! Je to sústo, ale možno tento diagram pomôže:
Znovu opakujem, skutočnou krásou PyPy je, že by sme si v RPythone mohli bez obáv o JIT napísať kopu rôznych interpretov Pythonu. PyPy by potom za nás implementoval JIT pomocou RPython Toolchain / PyPy (2).
V skutočnosti, ak sa dostaneme ešte abstraktnejšie, môžete teoreticky napísať tlmočník pre akýkoľvek jazyk, vložte ho do PyPy a získajte JIT pre tento jazyk. Je to preto, že program PyPy sa zameriava na optimalizáciu skutočného tlmočníka, a nie na podrobnosti jazyka, ktorý tlmočí.
Teoreticky by ste mohli napísať tlmočníka pre akýkoľvek jazyk, vložiť ho do PyPy a získať JIT pre daný jazyk.Na krátku odbočku by som rád spomenul, že samotný JIT je úplne fascinujúci. Používa techniku nazývanú trasovanie, ktorá sa vykonáva nasledovne :
Pre viac, tento papier je vysoko prístupný a veľmi zaujímavý.
Zhrnutie: na kompiláciu interpreta implementovaného pomocou PyPy RPython-to-C (alebo inej cieľovej platformy) používame kompilátor PyPy.
Po zdĺhavom porovnaní implementácií Pythonu si musím položiť otázku: Prečo je to také skvelé? Prečo sa tejto bláznivej myšlienky oplatí venovať? Myslím Alex Gaynor daj to dobre na jeho Blog : „[PyPy je budúcnosť], pretože [ponúka] vyššiu rýchlosť, väčšiu flexibilitu a je lepšou platformou pre rast Pythonu.“
V skratke:
Python 3000 (Py3k) : alternatívne pomenovanie pre Python 3.0, major, dozadu-nekompatibilný Vydanie Pythonu, ktoré sa dostalo na scénu v 2008 . Tím Py3k predpovedal, že to bude trvať päť rokov aby bola táto nová verzia plne prijatá. A kým najviac (varovanie: neoficiálne tvrdenie) Vývojári Pythonu naďalej používajú Python 2.x, ľudia si čoraz viac uvedomujú Py3k.
Numba : „kompilátor so špecializáciou just-in-time“, ktorý pridáva JIT komentovaný Pythonský kód. V najzákladnejších pojmoch mu dáte nejaké rady a urýchli to časti vášho kódu. Numba je súčasťou Anakonda distribúcia, sada balíkov na analýzu a správu údajov.
IPython : veľmi odlišné od všetkého ostatného diskutovaného. Výpočtové prostredie pre Python. Interaktívne s podporou súborov nástrojov GUI a skúseností s prehliadačom atď.
RubyPython : most medzi virtuálnymi počítačmi Ruby a Python. Umožňuje vložiť kód Python do vášho kódu Ruby. Vy určíte, kde sa Python začína a končí a RubyPython zaraďuje údaje medzi VM.
PyObjc : jazykové väzby medzi Pythonom a Objective-C, ktoré fungujú ako most medzi nimi. V praxi to znamená, že môžete využívať knižnice Objective-C (vrátane všetkého, čo potrebujete na vytvorenie aplikácií OS X) z kódu Pythonu a moduly Pythonu z kódu Objective-C. V tomto prípade je vhodné, aby bol CPython napísaný v jazyku C, čo je podmnožina Objective-C.
PyQt : zatiaľ čo program PyObjc vám dáva väzbu pre komponenty grafického používateľského rozhrania OS X, program PyQt robí to isté pre aplikačný rámec Qt, umožňuje vám vytvárať bohaté grafické rozhrania, pristupovať k databázam SQL atď. Ďalším nástrojom zameraným na priblíženie Pythonovej jednoduchosti iným rámcov .