Aš supratau, kad Python yra interpretuojama kalba... Tačiau kai žiūriu į savo Python pradinį kodą, matau .pyc
failus, kuriuos Windows identifikuoja kaip "Compiled Python Files". Iš kur jie atsiranda?
Aš' buvo suteikta suprasti, kad Python yra interpretuojama kalba...
Šis populiarus memas yra neteisingas arba, tiksliau, sukurtas neteisingai suprantant (natūralios) kalbos lygius: panaši klaida būtų sakyti, kad "Biblija yra knyga kietais viršeliais". Leiskite man paaiškinti šį palyginimą...
"Biblija" yra "knyga" ta prasme, kad ji yra klasė (faktinių, fizinių objektų, identifikuojamų kaip) knygos; knygos, identifikuojamos kaip "Biblijos egzemplioriai"; turėtų turėti kažką esminio bendro (turinį, nors net ir jis gali būti skirtingomis kalbomis, su skirtingais priimtinais vertimais, skirtingu išnašų ir kitų komentarų lygiu) - tačiau šios knygos gali skirtis daugybe aspektų, kurie nelaikomi esminiais - įrišimo rūšimi, įrišimo spalva, spausdinimui naudojamu (-ais) šriftu (-ais), iliustracijomis, jei tokių yra, plačiomis rašomomis paraštėmis ar ne, įrišamų knygų skirtukų skaičiumi ir rūšimis ir t. t., ir t. t., ir pan.
Visai įmanoma, kad tipinis Biblijos spausdinimas iš tiesų būtų kietais viršeliais - juk tai knyga, kurią paprastai ketinama skaityti vėl ir vėl, žymėti keliose vietose, vartyti, ieškant tam tikrų skyrių ir eilučių nuorodų, ir t. t., ir t. t., o geras kietas įrišimas gali padėti tam tikram egzemplioriui ilgiau išsilaikyti. Tačiau tai yra žemiški (praktiniai) dalykai, kuriais negalima remtis nustatant, ar konkretus knygos objektas yra Biblijos egzempliorius, ar ne: puikiai įmanomi ir popieriniai tiražai!
Panašiai Python yra "kalba" ta prasme, kad apibrėžia klasę kalbos implementacijų, kurios visos turi būti panašios tam tikrais esminiais aspektais (sintaksė, didžioji dalis semantikos, išskyrus tas jų dalis, kuriose joms'aiškiai leidžiama skirtis), tačiau joms visiškai leidžiama skirtis beveik kiekvienoje "įgyvendinimo" detalėmis - įskaitant tai, kaip jie elgiasi su jiems pateiktais pradiniais failais, ar jie kompiliuoja pradinius failus į žemesnio lygio formas (ir, jei taip, į kokias formas - ir ar jie išsaugo tokias kompiliuotas formas diske ar kitur), kaip jie vykdo minėtas formas ir t. t.
Klasikinė CPython realizacija dažnai vadinama tiesiog "Python", bet tai tik viena iš keleto gamybinės kokybės realizacijų, greta Microsoft IronPython (kuri kompiliuojama į CLR kodus, t. y., ".NET"), Jython (kuris kompiliuojamas į JVM kodus), PyPy (kuris parašytas pačia Python kalba ir gali būti kompiliuojamas į labai įvairias "back-end" formas, įskaitant "just-in-time" generuojamą mašininę kalbą). Visi jie yra Python (=="Python kalbos realizacijos"), kaip ir daugelis iš pažiūros skirtingų knygų objektų gali būti Biblija (=="Biblijos kopijos").
Jei jus domina konkrečiai CPython: jis kompiliuoja pradinius failus į Python būdingą žemesnio lygio formą (vadinamą "bytecode"), prireikus tai daro automatiškai (kai nėra bytecode failo, atitinkančio pradinį failą, arba bytecode failas yra senesnis už pradinį arba kompiliuotas kita Python versija), paprastai išsaugo bytecode failus diske (kad ateityje nereikėtų jų iš naujo kompiliuoti). O IronPython paprastai kompiliuoja į CLR kodus (išsaugo juos diske arba ne, priklausomai nuo to), o Jython - į JVM kodus (išsaugo juos diske arba ne - jei išsaugo, naudoja .class
plėtinį).
Tada šias žemesnio lygio formas vykdo atitinkamos "virtualios mašinos", dar vadinamos "interpretatoriais" -- CPython VM, .Net runtime, Java VM (dar vadinama JVM), priklausomai nuo situacijos.
Taigi šia prasme (ką daro tipinės realizacijos) Python yra "interpretuojamoji kalba" tada ir tik tada, kai C# ir Java yra tokios kalbos: visos jos turi tipinę realizacijos strategiją, pagal kurią pirmiausia sukuriamas baitkodas, o paskui jis vykdomas per virtualiąją mašiną ir (arba) interpretatorių.
Labiau tikėtina, kad dėmesys sutelkiamas į tai, koks "sunkus", lėtas ir daug pastangų reikalaujantis kompiliavimo procesas. CPython sukurtas taip, kad kompiliuotų kuo greičiau, kuo lengviau ir su kuo mažiau ceremonijų - kompiliatorius labai mažai tikrina klaidas ir optimizuoja, todėl jis gali veikti greitai ir su nedideliu atminties kiekiu, o tai savo ruožtu leidžia jį paleisti automatiškai ir skaidriai, kai tik reikia, o naudotojui dažniausiai net nereikia žinoti, kad vyksta kompiliavimas. Java ir C# paprastai priima daugiau darbo kompiliavimo metu (todėl nevykdo automatinio kompiliavimo), kad galėtų kruopščiau patikrinti klaidas ir atlikti daugiau optimizavimų. Tai'yra pilkosios skalės kontinuumas, o ne juoda ar balta situacija, ir būtų visiškai savavališka nustatyti tam tikro lygio ribą ir sakyti, kad tik virš šio lygio tai vadinama "kompiliavimu"!-)
Juose yra baitų kodas, į kurį "Python" vertėjas kompiliuoja šaltinį. Tada šį kodą vykdo "Python" virtualioji mašina.
Python'o dokumentuose apibrėžimas aiškinamas taip:
Python yra interpretuojamoji kalba, nes
priešingai nei kompiliuotoji, nors skirtumas gali būti neryškus dėl yra baitkodo kompiliatorius. Tai reiškia, kad šaltinio failai gali būti paleisti tiesiogiai be aiškaus sukuriant vykdomąją bylą, kuri vėliau paleidžiamas.
Juos sukuria Python vertėjas, kai importuojamas .py
failas, ir juose yra importuoto modulio/programos "sukompiliuotas baitkodas", o idėja yra ta, kad "vertimas" iš pradinio kodo į baitkodą (kurį reikia atlikti tik vieną kartą) gali būti praleistas vėlesnių importų metu, jei
.pycyra naujesnis nei atitinkamas
.py` failas, taip šiek tiek pagreitinant paleidimą. Tačiau jis vis tiek interpretuojamas.