Python yorumlanıyor, derleniyor veya her ikisi birden mi?


190

Anladığım kadarıyla:

Bir yorumlanmış dil halindeyken (yürütme sonra makine koduna üst düzey bir dil dönüştüren ve bir program) yüksek seviyeli bir dil çalıştırma ve bir tercüman tarafından yürütülen olduğu; programı her seferinde biraz işler.

Bir derlenmiş dil Kodu, ilk olarak bir uygulayıcısı (kod çalıştırmak için bir program) bir derleyici (makine kodu, üst düzey bir dil dönüştüren bir program) makine kodu dönüştürülebilir ve daha sonra çalıştırılan bir üst düzey bir dildir.

Tanımlarım yanlışsa beni düzeltin.

Şimdi Python'a geri dönüyorum, bu konuda biraz kafam karıştı. Her yerde Python'un yorumlanmış bir dil olduğunu öğrenirsiniz, ancak makine koduna değil , bazı ara kodlara (bayt kodu veya IL gibi) yorumlanır . Peki hangi program IM kodunu yürütür? Lütfen bir Python betiğinin nasıl işlendiğini ve çalıştırıldığını anlamama yardımcı olun.



2
Python, bir kitaplık içe aktarıldığında .pyc dosyaları (byecode olarak adlandırılır) oluşturur. AFAIK bayt kodu yürütme sürelerini değil, yalnızca yükleme sürelerini hızlandırabilir.
Jesvin Jose

2
@aitchnyu: Bayt kodunu .pyc dosyalarında önbelleğe almak yalnızca yüklemeyi hızlandırır, ancak yine de Python kodunun yürütmeden önce bayt koduna derlendiğinden. Özellikle Python ile denendiğini düşünmeme rağmen, diğer dil uygulamaları bayt kodun verimli bir şekilde yorumlanmasının basit bir AST veya daha da kötüsü ayrıştırılmamış kaynak kodundan daha kolay olduğunu göstermektedir. Eski Ruby sürümleri, örneğin AST'den yorumlandı ve AFAIK, bayt kodunu derleyen yeni sürümlerle biraz daha iyi performans gösterdi.

Kulağa kaba gelmek istemiyorum ama ne demek istediğimi değil (ama senin kadar bilgili değil)?
Jesvin Jose

1
@aitchnyu: Ne demek istediğini bilmiyorum. Sadece yorumunuzun yanlış olmadığını biliyorum, ancak neden sadece yükleme süresini hızlandırdığı bazı arka plan bilgileri için iyi bir fırsat sağladı , bu yüzden bu bilgileri eklemeye karar verdim. Hiçbir suç kastedildi veya alınmadı :)

Yanıtlar:


232

Öncelikle, yorumlanan / derlenen dilin bir özelliği değil, uygulamanın bir özelliğidir. Çoğu dil için, çoğu uygulama bir kategoriye girmiyorsa, dilin de yorumlandığını / derlendiğini söyleyen birkaç kelime kaydedilebilir, ancak hem anlamaya yardımcı olduğu hem de çok az dil olduğu için hala önemli bir ayrımdır. her iki türün de kullanılabilir uygulamaları ile (çoğunlukla fonksiyonel diller alanında, bkz. Haskell ve ML). Ek olarak, bir Python alt kümesini C veya C ++ koduna (ve daha sonra makine koduna) derlemeye çalışan C tercümanları ve projeleri vardır.

İkincisi, derleme, yerel makine koduyla önceden vaktinden derleme ile sınırlı değildir. Derleyici, daha genel olarak, bir programı bir programlama dilinde bir programı başka bir programlama dilinde bir programa dönüştüren bir programdır (önemli dönüşümler uygulanmışsa, aynı giriş ve çıkış diline sahip bir derleyiciye bile sahip olabilirsiniz). Ve JIT derleyicileri çalışma zamanında yerel makine kodunu derler , bu da zamanın derlemesine çok yakın veya hatta daha iyi hız verebilir (karşılaştırmaya ve uygulamaların kalitesine bağlı olarak).

Ancak nitelemeyi durdurmak ve sormak istediğiniz soruyu cevaplamak için: Pratik olarak (okuyun: biraz popüler ve olgun bir uygulama kullanarak), Python derlenir . Önceden makine koduna derlenmemiştir (yani, sınırlı ve yanlış tarafından "derlendi", ancak ne yazık ki ortak tanım), "sadece" bayt koduna derlendi , ancak yine de en azından bazı faydaları ile derleniyor . Örneğin, ifade a = b.c()"demonte edildiğinde" biraz benzeyen bir bayt akışına derlenir load 0 (b); load_str 'c'; get_attr; call_function 0; store 1 (a). Bu bir basitleştirme, aslında daha az okunabilir ve biraz daha düşük seviyeli - standart kütüphane dismodülünü deneyebilir ve gerçek anlaşmanın nasıl göründüğünü görebilirsiniz.

Bu bytecode ya referans uygulamada (CPython) olduğu gibi yorumlanır (hem teoride hem de pratik performansta, doğrudan ve ilk olarak bazı ara gösterimlere derleme ve yorumlama arasında bir fark vardır) veya hem yorumlanır hem de derlenir. PyPy'de olduğu gibi çalışma zamanında optimize edilmiş makine kodu .


2
Tamam, bu bir python betiğinin önce bayt koduna derlendiği ve daha sonra CPython, Jython veya IronPython vb. Gibi bir tercüman tarafından uygulandığı anlamına gelir.
Pankaj Upadhyay

19
Hayır, bayt koduna derlenir ve bayt kodu ilgili VM tarafından yürütülür. CPython hem derleyici hem de VM'dir, ancak Jython ve IronPython sadece derleyicidir.
Ignacio Vazquez-Abrams

1
@Igacio: IronPython / Jython ile pek tecrübem yok, ama en azından Jython tercüman benzeri bir katman sağlamıyor mu? Python'u statik olarak yazılmış JVM bayt koduna dönüştürmenin mümkün olduğuna inanmıyorum. Yine de derleyici ve yorumlayıcı aynı paketin bir parçası olmak için iyi bir nokta.

2
+1 "... uygulamanın bir özelliği". Ben kendim "interaktif bir kabuk için izin verir"
derdi

2
@delnan: Jython, Python dili ve Java VM arasında bir tür aracı görevi görür, ancak Java bayt kodunu derler.
Ignacio Vazquez-Abrams

34

CPU sadece makine kodunu anlayabilir. Yorumlanan programlar için, bir tercümanın nihai amacı program kodunu makine koduna "yorumlamaktır". Bununla birlikte, genellikle modern bir yorumlanmış dil, çok yetersiz olduğu için insan kodunu doğrudan yorumlamaz.

Python yorumlayıcısı önce insan kodunu okur ve makine koduna yorumlamadan önce bazı ara kodlara göre optimize eder. Bu nedenle, kodunuzun derlenmiş yürütülebilir dosyasını doğrudan çalıştırabileceğiniz C ++ 'dan farklı olarak, bir Python betiği çalıştırmak için her zaman başka bir programa ihtiyacınız vardır. Örneğin, c:\Python27\python.exeveya /usr/bin/python.


11
"Çalıştırmak için başka bir programa ihtiyaç duymak" konusunu seviyorum. Bu, bazı düşüncelerimin netleşmesine yardımcı oldu.
Matt

python.exe önce kodu optimize eder ve sonra onu yorumlar?
Koray Tugay

@KorayTugay, python.exe insan tarafından okunabilir metin kaynak kodu verildiğinde, önce en iyi duruma getirilmiş bayt kodu üretir, sonra bunu yorumlar (dediğiniz gibi); ancak, zaten bir bayt kod dosyası (önceden derlenmiş) olduğunda, ilk adımı yapmak zorunda kalmaz, bu da biraz zaman kazandırır.
GordonBGood

31

Cevap, hangi python uygulamasının kullanıldığına bağlıdır. CPython ( python'un standart uygulaması) veya Jython (java programlama dili ile entegrasyon için hedeflenmiş ) diyelim , ilk önce bayt koduna çevrilir ve kullandığınız python uygulamasına bağlı olarak, bu bycode karşılık gelen yorum için sanal makine . CPython için PVM (Python Sanal Makinesi) ve Jython için JVM (Java Sanal Makinesi).

Ancak başka bir standart CPython uygulaması olan PyPy kullandığınızı varsayalım . Tam Zamanında Derleyici kullanır .


Bayt koduna çeviri sırasında bir derleyiciye ihtiyacı var, hangisi bu?
RICKY

Pypy bir " Python " uygulaması değil , bir Python uygulamasıdır. Aslında Pypy, CPython'a bir alternatiftir ( pypy.org/features.html ).
Giorgio

13

Python'un resmi web sitesine göre, yorumlanmış bir dildir.

https://www.python.org/doc/essays/blurb/

Python, yorumlanmış, nesne yönelimli, üst düzey bir programlama dilidir ...

...

Derleme adımı olmadığından ...

...

Python yorumlayıcısı ve kapsamlı standart kütüphane mevcuttur ...

...

Bunun yerine, yorumlayıcı bir hata bulduğunda bir istisna oluşturur. Program istisnayı yakalamadığında, yorumlayıcı bir yığın izi yazdırır.


7

Evet, hem derlenmiş hem de yorumlanmış bir dildir. Öyleyse neden genel olarak yorumlanmış dil olarak adlandırıyoruz?

nasıl derlendiğini ve yorumlandığını görüyor musunuz?

Her şeyden önce, Java dünyasından iseniz cevabımı daha fazla beğeneceğinizi söylemek istiyorum.

Java birinci ila bayt kodu dönüştürülmüş olur, kaynak kodu Javac derleyici sonra yöneliktir JVM (yürütme amacıyla doğal kodu üretmek için sorumlu). Şimdi size Java'yı derlenmiş dil olarak adlandırdığımızı göstermek istiyorum çünkü gerçekten kaynak kodunu derlediğini ve .class dosyasını (hiçbir şey bytecode hariç) verdiğini görebiliyoruz :

javac Hello.java -------> Hello.class dosyası üretir

java Merhaba --------> Bayt yönlendirilmesi JVM yürütme amaçlı

Aynı şey python ile de olur, yani önce kaynak kodu derleyici aracılığıyla bayt koduna dönüştürülür ve daha sonra PVM'ye yönlendirilir (yürütme amacıyla yerel kodu oluşturmaktan sorumludur). Şimdi size Python'u yorumlanmış bir dil olarak adlandırdığımızı göstermek istiyorum, çünkü derleme sahnenin arkasında ve python kodunu çalıştırdığımızda:

python Hello.py -------> doğrudan kodu keser ve çıktının kodun sözdizimsel olarak doğru olduğunu kanıtladığını görebiliriz

@ python Hello.py doğrudan yürütüyor gibi görünüyor ama gerçekten ilk önce yürütme amacıyla yerel kodu üretmek için yorumlayıcı tarafından yorumlanan bayt kodunu üretir.

CPython - Hem derleme hem de yorumlama sorumluluğunu alır.

Daha fazla ayrıntıya ihtiyacınız varsa aşağıdaki satırlara bakın :

CPython'un kaynak kodunu derlediğinden bahsettiğim gibi, gerçek derleme cython yardımı ile gerçekleşiyor, sonra yorumlama CPython yardımı ile oluyor

Şimdi Java ve Python'da Just-In-Time derleyicisinin rolü hakkında biraz konuşalım

JVM'de, yürütme amacıyla yerel makine kodunu almak için bayt kodunu satır satır yorumlayan Java Yorumlayıcısı vardır, ancak Java bayt kodu bir yorumlayıcı tarafından yürütüldüğünde yürütme her zaman daha yavaş olacaktır. Peki çözüm nedir? çözüm, yorumlanabileceğinden çok daha hızlı yürütülebilen yerel kodu üreten Just-In-Time derleyicisidir . Bazı JVM satıcıları Java Interpreter kullanırken bazıları Just-In-Time derleyicisini kullanır . Referans: buraya tıklayın

Hızlı yürütme elde etmek için yorumlayıcı etrafında almak için python CPython yerine başka bir python uygulama ( PyPy ) kullanın . PyPy de dahil olmak üzere diğer python uygulamaları için tıklayınız .


6

Eğer (Java'yı bilirsiniz) {

Python kodu java gibi bayt koduna dönüştürülür.
Bu bayt kodu, her erişmeye çalıştığınızda yeniden yürütülür.

} else {

Python kodu başlangıçta bytecode adı verilen
ve makine diline oldukça yakın olan ancak gerçek makine kodu olmayan bir şeye dönüştürülür ,
böylece her bytecode tekrar çalıştırıldığında veya çalıştırıldığında

}


2

Neredeyse, Python'un yorumlanmış bir dil olduğunu söyleyebiliriz. Ancak, tam kaynak kodunu java dili gibi bayt koduna dönüştürmek için bir kez derleme işleminin bir kısmını python'da kullanıyoruz.


1

Yeni başlayanlar için

Python, komut dosyanızı çalıştırmadan önce otomatik olarak bayt kodu adı verilen derlenmiş koda derler.

Bir komut dosyasını çalıştırmak içe aktarma olarak değerlendirilmez ve .pyc oluşturulmaz.

Örneğin, başka bir xyz.py modülünü içe aktaran bir abc.py komut dosyanız varsa, abc.py komutunu çalıştırdığınızda, xyz içe aktarıldığından beri xyz.pyc oluşturulur, ancak abc'den bu yana abc.pyc dosyası oluşturulmaz. py ithal edilmiyor.


1

Python üzerinde çalışmaya başlayan insanlar için büyük bir karışıklık ve buradaki cevapları anlamak biraz zor, bu yüzden daha kolay yapacağım.

Python'a betiğimizi çalıştırmasını talimat verdiğimizde, kodumuz gerçekten bozulmaya başlamadan önce Python'un gerçekleştirdiği birkaç adım vardır:

  • Bayt koduna derlenir.
  • Sonra sanal makineye yönlendirilir.

Bir kaynak kodu yürüttüğümüzde, Python bunu bir bayt kodunda derler. Derleme bir çeviri adımıdır ve bayt kodu, kaynak kodun platformdan bağımsız olarak düşük düzeyli bir temsilidir. Python bayt kodunun ikili makine kodu olmadığını unutmayın (örn. Intel yongası için talimatlar).

Aslında Python, kaynak kodun her bir ifadesini ayrı ayrı adımlara ayırarak bayt kodu talimatlarına çevirir. Bayt kodu çevirisi işlemi hızlandırmak için yapılır. Bayt kodu, orijinal kaynak kodu ifadelerinden çok daha hızlı çalıştırılabilir. Uzantısı vardır .pyc ve makinemize yazabiliyorsa yazılacaktır.

Dolayısıyla, aynı programı bir sonraki çalıştırdığımızda, Python .pyc dosyasını yükleyecek ve değiştirilmedikçe derleme adımını atlayacaktır. Python, ne zaman yeniden derlenmesi gerektiğini bilmek için kaynak ve bayt kodu dosyalarının zaman damgalarını otomatik olarak kontrol eder. Kaynak kodu yeniden kaydedersek, programın bir sonraki çalıştırılışında otomatik olarak bayt kodu yeniden oluşturulur.

Python bayt kodu dosyalarını makinemize yazamazsa, programımız hala çalışır. Bayt kodu bellekte oluşturulur ve program çıkışında atılır. Ancak .pyc dosyaları başlangıç ​​zamanını hızlandırdığından, daha büyük programlar için yazıldığından emin olmak isteyebiliriz.

Perde arkasında neler olduğunu özetleyelim. Bir Python bir programı yürüttüğünde, Python .py'yi belleğe okur ve bir bayt kodu almak için onu ayrıştırır, ardından yürütmeye devam eder. Program tarafından içe aktarılan her modül için, Python önce .pyo veya .pyc dosyasında, .py dosyasına karşılık gelen bir zaman damgasına sahip önceden derlenmiş bir bayt kodu sürümü olup olmadığını kontrol eder. Python varsa bayt kodu sürümünü kullanır. Aksi takdirde, modülün .py dosyasını ayrıştırır, bir .pyc dosyasına kaydeder ve yeni oluşturduğu bayt kodunu kullanır.

Bayt kodu dosyaları da Python kodlarını göndermenin bir yoludur. Python, orijinal .py kaynak dosyaları olmasa bile, bulabildiği her şey are.pyc dosyalarını çalıştırsa bile bir program çalıştıracaktır.

Python Sanal Makinesi (PVM)

Programımız bayt koduna derlendikten sonra, Python Virtual Machine (PVM) 'ye yürütmek üzere gönderilir. PVM ayrı bir program değildir. Kendi başına kurulmasına gerek yoktur. Aslında, PVM sadece bayt kodu talimatımızı kullanarak işlemlerini tek tek yapmak için yinelenen büyük bir döngüdür. PVM, Python'un çalışma zamanı motorudur. Her zaman Python sisteminin bir parçası olarak bulunur. Komut dosyalarımızı gerçekten çalıştıran bileşendir. Teknik olarak Python yorumlayıcısının son adımıdır.


0

Yazdığınız python kodu, .pyc uzantılı dosya oluşturan python bayt kodunda derlenir. Eğer derlerse, yine soru, neden derlenmiş dil değildir.

Bunun kelimenin geleneksel anlamında bir derleme olmadığını unutmayın. Genellikle derlemenin üst düzey bir dil alıp makine koduna dönüştürdüğünü söyleyebiliriz. Ama bu bir tür derlemedir. Makine koduna değil ara koda derlenmiştir (Şimdi anladınız).

Yürütme işlemine geri dönersek, derleme adımında oluşturulan pyc dosyasında bulunan bayt kodunuz uygun sanal makineler tarafından yürütülür, bizim durumumuzda, CPython VM Zaman damgası (sihirli sayı olarak adlandırılır) doğrulamak için kullanılır. Bu yeni pyc dosyasının oluşturulmasına bağlı olarak py dosyası değiştirilir veya değiştirilmez. Pyc geçerli kodda ise, derleme adımını atlar.


0

Python (yorumlayıcı) derlenir .

İspat: Sözdizimi hatası içeriyorsa kodunuzu derlemeyecektir .

Örnek 1:

print("This should print") 
a = 9/0 

Çıktı:

This should print
Traceback (most recent call last):
  File "p.py", line 2, in <module>
    a = 9/0
ZeroDivisionError: integer division or modulo by zero

Kod başarıyla derlendi. İlk satır çalıştırılır ( print) ikinci satır atılır ZeroDivisionError(çalışma süresi hatası).

Örnek 2:

print("This should not print")
/0         

Çıktı:

  File "p.py", line 2
    /0
    ^
SyntaxError: invalid syntax

Sonuç : Kod dosyanız SyntaxErrorhiçbir şey içermiyorsa, derleme başarısız olduğundan yürütülür.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.