Apakah Python ditafsirkan, atau dikompilasi, atau keduanya?

190

Dari pengertian saya:

Sebuah ditafsirkan bahasa adalah bahasa tingkat tinggi yang dikelola dan dijalankan oleh seorang penerjemah (program yang mengubah bahasa tingkat tinggi ke kode mesin dan kemudian mengeksekusi) di mana saja; itu memproses program sedikit demi sedikit.

Sebuah disusun bahasa adalah bahasa tingkat tinggi yang kode pertama dikonversi ke mesin-kode oleh compiler (program yang mengubah bahasa tingkat tinggi ke kode mesin) dan kemudian dieksekusi oleh eksekutor (program lain untuk menjalankan kode).

Perbaiki saya jika definisi saya salah.

Sekarang kembali ke Python, saya agak bingung tentang ini. Di mana-mana Anda mengetahui bahwa Python adalah bahasa yang ditafsirkan, tetapi ditafsirkan ke beberapa kode perantara (seperti kode byte atau IL) dan bukan ke kode mesin. Jadi program mana yang mengeksekusi kode IM? Tolong bantu saya memahami bagaimana skrip Python ditangani dan dijalankan.

Pankaj Upadhyay
sumber
2
Python memang membuat file .pyc (disebut byecode) setiap kali perpustakaan diimpor. AFAIK bytecode hanya dapat mempercepat waktu muat, bukan waktu eksekusi.
Jesvin Jose
2
@aitchnyu: Caching bytecode di file .pyc memang mempercepat loading, tetapi karena kode Python dikompilasi ke bytecode sebelum dieksekusi. Meskipun saya tidak berpikir itu telah dicoba dengan Python secara khusus, implementasi bahasa lain menunjukkan bahwa bytecode memang lebih mudah untuk ditafsirkan secara efisien daripada AST biasa atau, lebih buruk lagi, kode sumber tidak diuraikan. Versi Ruby yang lebih lama diinterpretasikan dari AST, misalnya, dan AFAIK sedikit dikalahkan oleh versi yang lebih baru yang dikompilasi ke bytecode.
Tidak ingin terdengar kasar, tetapi bukankah itu yang saya maksudkan (tapi tidak sepengetahuan Anda)?
Jesvin Jose
1
@aitchnyu: Saya tidak tahu apa yang Anda maksud. Saya hanya tahu bahwa komentar Anda tidak salah tetapi memberikan peluang yang bagus untuk beberapa info latar belakang mengapa hanya mempercepat waktu muat, jadi saya memutuskan untuk menambahkan informasi itu. Tidak ada pelanggaran berarti atau diambil :)

Jawaban:

232

Pertama, ditafsirkan / dikompilasi bukan properti bahasa tetapi properti implementasi. Untuk sebagian besar bahasa, sebagian besar jika tidak semua implementasi termasuk dalam satu kategori, jadi orang mungkin menyimpan beberapa kata yang mengatakan bahasa tersebut ditafsirkan / dikompilasi juga, tetapi itu masih merupakan perbedaan penting, baik karena membantu pemahaman dan karena ada beberapa bahasa dengan implementasi yang dapat digunakan dari kedua jenis (sebagian besar di bidang bahasa fungsional, lihat Haskell dan ML). Selain itu, ada juru bahasa C dan proyek yang berusaha untuk mengkompilasi subset kode Python ke C atau C ++ (dan selanjutnya ke kode mesin).

Kedua, kompilasi tidak terbatas pada kompilasi sebelumnya ke kode mesin asli. Kompiler adalah, secara umum, program yang mengubah program dalam satu bahasa pemrograman menjadi program dalam bahasa pemrograman lain (bisa dibilang, Anda bahkan dapat memiliki kompiler dengan bahasa input dan output yang sama jika transformasi signifikan diterapkan). Dan kompiler JIT mengkompilasi kode mesin asli saat runtime , yang dapat memberikan kecepatan sangat dekat atau bahkan lebih baik daripada kompilasi sebelumnya (tergantung pada tolok ukur dan kualitas implementasi dibandingkan).

Tetapi untuk menghentikan nitpicking dan menjawab pertanyaan yang ingin Anda tanyakan: Praktis (baca: menggunakan implementasi yang agak populer dan matang), Python dikompilasi . Tidak dikompilasi dengan kode mesin sebelumnya (yaitu "dikompilasi" oleh batasan dan salah, tetapi sayangnya definisi umum), "hanya" dikompilasi ke bytecode , tetapi masih dikompilasi dengan setidaknya beberapa manfaat. Misalnya, pernyataan a = b.c()dikompilasi ke aliran byte yang, ketika "dibongkar", terlihat seperti load 0 (b); load_str 'c'; get_attr; call_function 0; store 1 (a). Ini adalah penyederhanaan, sebenarnya kurang dapat dibaca dan sedikit lebih rendah - Anda dapat bereksperimen dengan dismodul perpustakaan standar dan melihat seperti apa sebenarnya.

Bytecode itu ditafsirkan (perhatikan bahwa ada perbedaan, baik dalam teori dan kinerja praktis, antara menafsirkan secara langsung dan pertama mengkompilasi ke beberapa representasi perantara dan menafsirkannya), seperti dengan implementasi referensi (CPython), atau keduanya ditafsirkan dan dikompilasi untuk kode mesin dioptimalkan saat runtime, seperti halnya PyPy .

jsmedmar
sumber
2
Baiklah, ini berarti bahwa skrip python pertama kali dikompilasi ke bytecode dan kemudian diimplementasikan oleh penerjemah seperti CPython, Jython atau IronPython dll.
Pankaj Upadhyay
19
Tidak, ini dikompilasi ke bytecode dan kemudian bytecode dijalankan oleh masing-masing VM. CPython adalah kompiler dan VM, tetapi Jython dan IronPython hanyalah kompiler.
Ignacio Vazquez-Abrams
1
@ Igacio: Saya tidak punya banyak pengalaman dengan IronPython / Jython, tetapi tidakkah setidaknya Jython menyediakan lapisan seperti juru bahasa? Saya tidak percaya itu layak untuk mencoba mengubah Python menjadi bytecode JVM yang diketik secara statis. Namun, poin bagus tentang kompiler dan interpreter menjadi bagian dari paket yang sama.
2
+1 "... properti dari implementasi". Saya sendiri akan mengatakan "itu memungkinkan untuk shell interaktif"
Jesvin Jose
2
@delnan: Ya, Jython bertindak sebagai semacam perantara antara bahasa Python dan Java VM, tetapi kompilasi ke bytecode Java.
Ignacio Vazquez-Abrams
34

CPU memang hanya bisa memahami kode mesin. Untuk program yang ditafsirkan, tujuan utama seorang juru bahasa adalah untuk "menafsirkan" kode program ke dalam kode mesin. Namun, biasanya bahasa yang ditafsirkan modern tidak menafsirkan kode manusia secara langsung karena terlalu tidak efisien.

Penerjemah Python pertama kali membaca kode manusia dan mengoptimalkannya ke beberapa kode perantara sebelum menafsirkannya menjadi kode mesin. Itu sebabnya Anda selalu membutuhkan program lain untuk menjalankan skrip Python, tidak seperti di C ++ di mana Anda dapat menjalankan executable yang dikompilasi dari kode Anda secara langsung. Misalnya, c:\Python27\python.exeatau /usr/bin/python.

Jeremy
sumber
11
Saya suka poin tentang "membutuhkan program lain untuk menjalankannya". Itu membantu memperjelas beberapa pemikiran saya.
Mat
jadi python.exe pertama mengoptimalkan kode dan kemudian mengartikannya?
Koray Tugay
@ KorayTugay, ketika python.exe diberikan kode sumber teks yang dapat dibaca manusia, pertama-tama menghasilkan kode byte yang dioptimalkan, kemudian menafsirkannya (seperti yang Anda katakan); Namun, ketika sudah ada file kode byte (pra-kompilasi), itu tidak harus melakukan langkah pertama, yang menghemat waktu.
GordonBGood
31

Jawabannya tergantung pada implementasi python apa yang digunakan. Jika Anda menggunakan katakanlah CPython (Implementasi standar python) atau Jython (Ditargetkan untuk integrasi dengan bahasa pemrograman java) pertama-tama diterjemahkan ke dalam bytecode , dan tergantung pada implementasi python yang Anda gunakan, bycode ini diarahkan ke yang sesuai mesin virtual untuk interpretasi . PVM (Mesin Virtual Python) untuk CPython dan JVM (Mesin Virtual Java) untuk Jython.

Tetapi katakanlah Anda menggunakan PyPy yang merupakan implementasi standar CPython lainnya. Itu akan menggunakan Compiler Just-In-Time .

uji kualitas
sumber
Selama terjemahan ke bytecode itu memang membutuhkan kompiler yang mana?
RICKY
Pypy adalah implementasi Python , bukan implementasi "CPython". Bahkan, Pypy adalah alternatif untuk CPython ( pypy.org/features.html ).
Giorgio
13

Menurut situs resmi Python itu adalah bahasa yang diartikan.

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

Python adalah bahasa pemrograman tingkat tinggi yang ditafsirkan, berorientasi objek, ...

...

Karena tidak ada langkah kompilasi ...

...

Penerjemah Python dan perpustakaan standar luas tersedia ...

...

Sebaliknya, ketika penerjemah menemukan kesalahan, itu menimbulkan pengecualian. Ketika program tidak menangkap pengecualian, penerjemah mencetak jejak tumpukan.

John S.
sumber
7

Ya, itu adalah bahasa yang dikompilasi dan ditafsirkan. Lalu mengapa kita umumnya menyebutnya sebagai bahasa yang ditafsirkan?

lihat bagaimana keduanya dikompilasi dan diinterpretasikan?

Pertama-tama saya ingin mengatakan bahwa Anda akan lebih menyukai jawaban saya jika Anda berasal dari dunia Jawa.

Di Java, kode sumber pertama-tama akan dikonversi ke kode byte melalui javac compiler kemudian diarahkan ke JVM (bertanggung jawab untuk menghasilkan kode asli untuk tujuan eksekusi). Sekarang saya ingin menunjukkan kepada Anda bahwa kita memanggil Java sebagai bahasa yang dikompilasi karena kita dapat melihat bahwa itu benar-benar mengkompilasi kode sumber dan memberikan file .class (tidak ada tapi bytecode) melalui:

javac Hello.java -------> menghasilkan file Hello.class

java Hello --------> Mengarahkan bytecode ke JVM untuk tujuan eksekusi

Hal yang sama terjadi dengan python yaitu pertama kode sumber akan dikonversi ke bytecode melalui kompiler kemudian diarahkan ke PVM (bertanggung jawab untuk menghasilkan kode asli untuk tujuan eksekusi). Sekarang saya ingin menunjukkan kepada Anda bahwa kami biasanya memanggil Python sebagai bahasa yang ditafsirkan karena kompilasi terjadi di belakang layar dan ketika kami menjalankan kode python melalui:

python Hello.py -------> langsung mengeluarkan kode dan kita dapat melihat output yang diberikan kode yang secara sintaksis benar

@ python Hello.py sepertinya langsung dieksekusi tetapi benar-benar pertama-tama menghasilkan bytecode yang ditafsirkan oleh interpreter untuk menghasilkan kode asli untuk tujuan eksekusi.

CPython - Mengambil tanggung jawab atas kompilasi dan interpretasi.

Lihatlah garis-garis di bawah ini jika Anda perlu lebih detail :

Seperti yang saya sebutkan bahwa CPython mengkompilasi kode sumber tetapi kompilasi yang sebenarnya terjadi dengan bantuan cython kemudian interpretasi terjadi dengan bantuan CPython

Sekarang mari kita bicara sedikit tentang peran kompiler Just-In-Time di Jawa dan Python

Di JVM ada Java Interpreter yang menginterpretasikan bytecode baris demi baris untuk mendapatkan kode mesin asli untuk tujuan eksekusi tetapi ketika Java bytecode dieksekusi oleh interpreter, eksekusi akan selalu lebih lambat. Jadi apa solusinya? solusinya adalah kompiler Just-In-Time yang menghasilkan kode asli yang dapat dieksekusi lebih cepat daripada yang bisa ditafsirkan. Beberapa vendor JVM menggunakan Java Interpreter dan beberapa menggunakan Just-In-Time compiler . Referensi: klik di sini

Dalam python untuk berkeliling penerjemah untuk mencapai eksekusi cepat menggunakan implementasi python lain ( PyPy ), bukan CPython . klik di sini untuk implementasi python lainnya termasuk PyPy .

chirag soni
sumber
6

If (You know Java) {

kode Python dikonversi menjadi bytecode seperti halnya java.
Bytecode dieksekusi lagi setiap kali Anda mencoba mengaksesnya.

} else {

Kode Python pada awalnya traslated menjadi sesuatu yang disebut bytecode
yang cukup dekat dengan bahasa mesin tetapi bukan kode mesin yang sebenarnya
sehingga setiap kali kita mengakses atau menjalankannya bytecode dieksekusi lagi

}

Nabil Qadir
sumber
2

Hampir, kita dapat mengatakan Python adalah bahasa yang ditafsirkan. Tetapi kami menggunakan beberapa bagian dari proses kompilasi satu kali dalam python untuk mengubah kode sumber lengkap menjadi kode byte seperti bahasa java.

Hemant
sumber
1

Untuk pemula

Python secara otomatis mengkompilasi skrip Anda ke kode yang dikompilasi, yang disebut kode byte, sebelum menjalankannya.

Menjalankan skrip tidak dianggap sebagai impor dan no .pyc akan dibuat.

Misalnya, jika Anda memiliki file skrip abc.py yang mengimpor modul lain xyz.py, saat Anda menjalankan abc.py, xyz.pyc akan dibuat sejak xyz diimpor, tetapi tidak ada file abc.pyc yang akan dibuat sejak abc. py tidak diimpor.

navaneeth kt
sumber
1

Ini adalah kebingungan besar bagi orang-orang yang mulai mengerjakan python dan jawabannya di sini sedikit sulit untuk dipahami sehingga saya akan membuatnya lebih mudah.

Saat kami memerintahkan Python untuk menjalankan skrip kami, ada beberapa langkah yang dilakukan Python sebelum kode kami benar-benar mulai berangsur-angsur hilang:

  • Ini dikompilasi ke bytecode.
  • Kemudian diarahkan ke mesin virtual.

Ketika kita mengeksekusi kode sumber, Python mengkompilasinya menjadi kode byte. Kompilasi adalah langkah terjemahan, dan kode byte adalah representasi independen kode sumber tingkat rendah platform-level. Perhatikan bahwa kode byte Python bukan kode mesin biner (misalnya, instruksi untuk chip Intel).

Sebenarnya, Python menerjemahkan setiap pernyataan dari kode sumber ke dalam instruksi kode byte dengan menguraikannya menjadi langkah-langkah individual. Terjemahan kode byte dilakukan untuk mempercepat eksekusi. Kode byte dapat dijalankan lebih cepat daripada pernyataan kode sumber asli. Ekstensi has.pyc dan akan ditulis jika dapat menulis ke mesin kami.

Jadi, lain kali kita menjalankan program yang sama, Python akan memuat file .pyc dan melewati langkah kompilasi kecuali jika sudah diubah. Python secara otomatis memeriksa stempel waktu dari file kode sumber dan byte untuk mengetahui kapan harus mengkompilasi ulang. Jika kita menyimpan kembali kode sumber, kode byte secara otomatis dibuat lagi pada saat program dijalankan.

Jika Python tidak dapat menulis file kode byte ke mesin kami, program kami masih berfungsi. Kode byte dihasilkan dalam memori dan dibuang begitu saja pada saat keluar dari program. Tetapi karena file .pyc mempercepat waktu startup, kami mungkin ingin memastikan itu telah ditulis untuk program yang lebih besar.

Mari kita simpulkan apa yang terjadi di balik layar. Ketika Python mengeksekusi sebuah program, Python membaca .py ke dalam memori, dan mem-parsingnya untuk mendapatkan bytecode, kemudian melanjutkan untuk mengeksekusi. Untuk setiap modul yang diimpor oleh program, Python terlebih dahulu memeriksa untuk melihat apakah ada versi bytecode yang dikompilasi, dalam .pyo atau .pyc, yang memiliki cap waktu yang sesuai dengan file .py-nya. Python menggunakan versi bytecode jika ada. Jika tidak, ia mem-parsing file .py modul, menyimpannya menjadi file .pyc, dan menggunakan bytecode yang baru saja dibuat.

File kode byte juga merupakan salah satu cara pengiriman kode Python. Python masih akan menjalankan program jika semua itu dapat menemukan file .pyc, bahkan jika file sumber .py asli tidak ada.

Mesin Virtual Python (PVM)

Setelah program kami dikompilasi ke dalam kode byte, program tersebut dikirim untuk dieksekusi ke Python Virtual Machine (PVM). PVM bukan program terpisah. Itu tidak perlu diinstal dengan sendirinya. Sebenarnya, PVM hanyalah sebuah loop besar yang berulang melalui instruksi kode byte kami, satu per satu, untuk melakukan operasi mereka. PVM adalah mesin runtime dari Python. Itu selalu hadir sebagai bagian dari sistem Python. Ini adalah komponen yang benar-benar menjalankan skrip kami. Secara teknis itu hanya langkah terakhir dari apa yang disebut interpreter Python.

erastone
sumber
0

Kode python yang Anda tulis dikompilasi ke dalam bytecode python, yang membuat file dengan ekstensi .pyc. Jika dikompilasi, sekali lagi pertanyaannya adalah, mengapa tidak dikompilasi bahasa.

Perhatikan bahwa ini bukan kompilasi dalam arti kata tradisional. Biasanya, kami akan mengatakan bahwa kompilasi mengambil bahasa tingkat tinggi dan mengubahnya menjadi kode mesin. Tapi itu adalah kompilasi. Dikompilasi menjadi kode perantara tidak menjadi kode mesin (Semoga Anda mendapatkannya sekarang).

Kembali ke proses eksekusi, bytecode Anda, hadir dalam file pyc, dibuat dalam langkah kompilasi, kemudian dieksekusi oleh mesin virtual yang sesuai, dalam kasus kami, VM CPython Cap waktu (disebut sebagai nomor ajaib) digunakan untuk memvalidasi apakah. file py diubah atau tidak, tergantung pada file pyc baru dibuat. Jika pyc adalah kode saat ini maka ia hanya melewatkan langkah kompilasi.

y durga prasad
sumber
0

Python (interpreter) dikompilasi .

Bukti: Bahkan tidak akan mengkompilasi kode Anda jika mengandung kesalahan sintaksis .

Contoh 1:

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

Keluaran:

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

Kode berhasil dikompilasi. Baris pertama dijalankan ( print) lemparan baris kedua ZeroDivisionError(run time error).

Contoh 2:

print("This should not print")
/0         

Keluaran:

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

Kesimpulan : Jika file kode Anda SyntaxErrortidak mengandung apa pun akan dieksekusi karena kompilasi gagal.

BlackBeard
sumber