Saya telah diberikan untuk memahami bahwa Python adalah bahasa yang ditafsirkan ...
Namun, ketika saya melihat kode sumber Python saya melihat .pyc
file, yang Windows mengidentifikasi sebagai "Compiled Python Files".
Di mana ini masuk?
python
compiled
interpreted-language
pyc
froadie
sumber
sumber
java
danjavac
.Jawaban:
Mereka mengandung kode byte , yang merupakan kompilasi dari sumber interpreter Python. Kode ini kemudian dieksekusi oleh mesin virtual Python.
Dokumentasi Python menjelaskan definisi seperti ini:
sumber
Meme populer ini tidak benar, atau, lebih tepatnya, dibangun di atas kesalahpahaman tingkat bahasa (alami): kesalahan yang sama akan mengatakan "Alkitab adalah buku hardcover". Biarkan saya jelaskan perumpamaan itu ...
"Alkitab" adalah "sebuah buku" dalam arti menjadi kelas dari (sebenarnya, objek fisik yang diidentifikasi sebagai) buku; buku-buku yang diidentifikasi sebagai "salinan Alkitab" seharusnya memiliki kesamaan yang mendasar (isinya, meskipun bahkan bisa dalam bahasa yang berbeda, dengan terjemahan yang dapat diterima berbeda, tingkat catatan kaki dan anotasi lainnya) - namun, buku-buku itu adalah sangat diizinkan untuk berbeda dalam banyak aspek yang tidak dianggap mendasar - jenis penjilidan, warna penjilidan, font yang digunakan dalam pencetakan, ilustrasi jika ada, margin yang dapat ditulis atau tidak, jumlah dan jenis penanda bawaan , dan sebagainya, dan sebagainya.
Sangat mungkin bahwa pencetakan Alkitab yang khas tentu saja akan mengikat hardcover - setelah semua, itu adalah buku yang biasanya dimaksudkan untuk dibaca berulang-ulang, di-bookmark di beberapa tempat, dibolak-balik mencari petunjuk bab dan ayat yang diberikan , dll, dll, dan penjilidan hardcover yang baik dapat membuat salinan yang diberikan bertahan lebih lama saat digunakan. Namun, ini adalah masalah duniawi (praktis) yang tidak dapat digunakan untuk menentukan apakah objek buku yang sebenarnya adalah salinan Alkitab atau tidak: cetakan paperback sangat mungkin!
Demikian pula, Python adalah "bahasa" dalam arti mendefinisikan kelas implementasi bahasa yang semuanya harus serupa dalam beberapa hal mendasar (sintaksis, sebagian besar semantik kecuali bagian-bagian yang secara eksplisit diizinkan berbeda) tetapi diizinkan sepenuhnya berbeda dalam setiap detail "implementasi" - termasuk bagaimana mereka berurusan dengan file sumber yang diberikan, apakah mereka mengkompilasi sumber ke beberapa formulir tingkat yang lebih rendah (dan, jika demikian, bentuk mana - dan apakah mereka menyimpannya formulir yang dikompilasi, ke disk atau tempat lain), bagaimana mereka mengeksekusi formulir tersebut, dan sebagainya.
Implementasi klasik, CPython, sering disebut hanya "Python" singkatnya - tetapi itu hanya salah satu dari beberapa implementasi kualitas produksi, berdampingan dengan IronPython Microsoft (yang mengkompilasi ke kode CLR, yaitu, ".NET"), Jython (yang mengkompilasi kode JVM), PyPy (yang ditulis dengan Python sendiri dan dapat dikompilasi ke berbagai macam bentuk "back-end" termasuk "just-in-time" bahasa mesin yang dihasilkan). Mereka semua adalah Python (== "implementasi bahasa Python") sama seperti banyak objek buku yang berbeda-beda semua bisa menjadi Alkitab (== "salinan Alkitab").
Jika Anda tertarik pada CPython secara spesifik: ia mengkompilasi file sumber ke dalam bentuk tingkat rendah spesifik-Python (dikenal sebagai "bytecode"), melakukannya secara otomatis ketika diperlukan (ketika tidak ada file bytecode yang sesuai dengan file sumber, atau file bytecode lebih tua dari sumber atau dikompilasi oleh versi Python yang berbeda), biasanya menyimpan file bytecode ke disk (untuk menghindari kompilasi ulang mereka di masa depan). OTOH IronPython biasanya akan dikompilasi ke kode CLR (menyimpannya ke disk atau tidak, tergantung) dan Jython ke kode JVM (menyimpannya ke disk atau tidak - itu akan menggunakan
.class
ekstensi jika itu menyimpannya).Bentuk-bentuk tingkat yang lebih rendah ini kemudian dijalankan oleh "mesin virtual" yang sesuai juga dikenal sebagai "juru bahasa" - VM CPython, runtime .Net, Java VM (alias JVM), yang sesuai.
Jadi, dalam pengertian ini (apa yang dilakukan implementasi tipikal), Python adalah "bahasa yang diartikan" jika dan hanya jika C # dan Java adalah: semuanya memiliki strategi implementasi yang khas untuk menghasilkan bytecode terlebih dahulu, kemudian menjalankannya melalui VM / interpreter .
Lebih mungkin fokusnya adalah pada seberapa "berat", lambat, dan tinggi upacara proses kompilasi. CPython dirancang untuk mengkompilasi secepat mungkin, seringan mungkin, dengan upacara sesedikit mungkin - kompiler melakukan pengecekan dan optimasi kesalahan yang sangat sedikit, sehingga dapat berjalan cepat dan dalam jumlah kecil memori, yang pada gilirannya memungkinkannya dijalankan secara otomatis dan transparan kapan pun diperlukan, tanpa pengguna bahkan perlu menyadari bahwa ada kompilasi yang terjadi, sebagian besar waktu. Java dan C # biasanya menerima lebih banyak pekerjaan selama kompilasi (dan karenanya tidak melakukan kompilasi otomatis) untuk memeriksa kesalahan lebih menyeluruh dan melakukan lebih banyak optimasi. Ini adalah rangkaian skala abu-abu, bukan situasi hitam atau putih,
sumber
Tidak ada bahasa yang ditafsirkan. Apakah penerjemah atau kompiler digunakan adalah murni sifat implementasi dan sama sekali tidak ada hubungannya dengan bahasa.
Setiap bahasa dapat diimplementasikan oleh penerjemah atau kompiler. Sebagian besar bahasa memiliki setidaknya satu implementasi dari setiap jenis. (Misalnya, ada penerjemah untuk C dan C ++ dan ada kompiler untuk JavaScript, PHP, Perl, Python, dan Ruby.) Selain itu, sebagian besar implementasi bahasa modern sebenarnya menggabungkan juru bahasa dan kompiler (atau bahkan beberapa kompiler).
Bahasa hanyalah seperangkat aturan matematika abstrak. Seorang juru bahasa adalah salah satu dari beberapa strategi implementasi konkret untuk suatu bahasa. Keduanya hidup pada level abstraksi yang sangat berbeda. Jika bahasa Inggris adalah bahasa yang diketik, istilah "bahasa yang ditafsirkan" akan menjadi kesalahan ketik. Pernyataan "Python adalah bahasa yang ditafsirkan" bukan hanya salah (karena salah akan menyiratkan bahwa pernyataan itu bahkan masuk akal, bahkan jika itu salah), itu hanya tidak masuk akal , karena bahasa tidak pernah dapat didefinisikan sebagai "ditafsirkan."
Secara khusus, jika Anda melihat implementasi Python yang ada saat ini, ini adalah strategi implementasi yang mereka gunakan:
Anda mungkin memperhatikan bahwa setiap implementasi dalam daftar itu (ditambah beberapa lainnya yang tidak saya sebutkan, seperti tinypy, Shedskin atau Psyco) memiliki kompiler. Bahkan, sejauh yang saya tahu, saat ini tidak ada implementasi Python yang murni ditafsirkan, tidak ada implementasi yang direncanakan dan tidak pernah ada implementasi seperti itu.
Tidak hanya istilah "bahasa yang ditafsirkan" tidak masuk akal, bahkan jika Anda menafsirkannya sebagai "bahasa dengan implementasi yang ditafsirkan", itu jelas tidak benar. Siapa pun yang memberi tahu Anda hal itu, jelas tidak tahu apa yang ia bicarakan.
Secara khusus,
.pyc
file yang Anda lihat adalah file bytecode di-cache yang dihasilkan oleh CPython, Stackless Python atau Unladen Swallow.sumber
Ini dibuat oleh interpreter Python ketika
.py
file diimpor, dan mereka berisi "dikompilasi bytecode" dari modul / program yang diimpor, idenya adalah bahwa "terjemahan" dari kode sumber ke bytecode (yang hanya perlu dilakukan sekali) dapat dilewati padaimport
s berikutnya jika.pyc
lebih baru dari.py
file yang sesuai , sehingga mempercepat startup. Tapi itu masih ditafsirkan.sumber
Untuk mempercepat memuat modul, Python cache konten yang dikompilasi modul dalam .pyc.
CPython mengkompilasi kode sumbernya menjadi "kode byte", dan untuk alasan kinerja, kode cache ini disimpan dalam sistem file setiap kali file sumber mengalami perubahan. Ini membuat pemuatan modul Python lebih cepat karena fase kompilasi dapat dilewati. Ketika file sumber Anda adalah foo.py, CPython membuat cache kode byte dalam file foo.pyc tepat di sebelah sumber.
Dalam python3, mesin impor Python diperluas untuk menulis dan mencari file cache kode byte dalam satu direktori di dalam setiap direktori paket Python. Direktori ini akan disebut __pycache__.
Berikut adalah bagan alur yang menjelaskan bagaimana modul dimuat:
Untuk informasi lebih lanjut:
ref: PEP3147
ref: File Python "Dikompilasi"
sumber
INI 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.
Jika Anda perlu membuat file .pyc untuk modul yang tidak diimpor, Anda dapat menggunakan
py_compile
dancompileall
modul.The
py_compile
modul dapat secara manual mengkompilasi modul apapun. Salah satu caranya adalah dengan menggunakanpy_compile.compile
fungsi dalam modul itu secara interaktif:Ini akan menulis .pyc ke lokasi yang sama dengan abc.py (Anda dapat menimpanya dengan parameter opsional
cfile
).Anda juga dapat secara otomatis mengkompilasi semua file dalam direktori atau direktori menggunakan modul compileall.
Jika nama direktori (direktori saat ini dalam contoh ini) dihilangkan, modul mengkompilasi semua yang ditemukan
sys.path
sumber
Python (setidaknya implementasi yang paling umum dari itu) mengikuti pola kompilasi sumber asli ke kode byte, kemudian menafsirkan kode byte pada mesin virtual. Ini berarti (sekali lagi, implementasi yang paling umum) bukanlah penerjemah murni atau kompilator murni.
Sisi lain dari ini adalah, bagaimanapun, bahwa proses kompilasi sebagian besar disembunyikan - file .pyc pada dasarnya diperlakukan seperti cache; mereka mempercepat, tetapi Anda biasanya tidak harus menyadarinya sama sekali. Secara otomatis membatalkan dan memuatnya kembali (kompilasi ulang kode sumber) bila perlu berdasarkan waktu file / tanggal perangko.
Satu-satunya saat saya melihat masalah dengan ini adalah ketika file bytecode yang dikompilasi entah bagaimana mendapat cap waktu di masa depan, yang berarti selalu terlihat lebih baru daripada file sumber. Karena terlihat lebih baru, file sumber tidak pernah dikompilasi ulang, jadi apa pun perubahan yang Anda buat, mereka diabaikan ...
sumber
File * .py Python hanyalah file teks tempat Anda menulis beberapa baris kode. Saat Anda mencoba menjalankan file ini menggunakan say "python filename.py"
Perintah ini memanggil Python Virtual Machine. Python Virtual Machine memiliki 2 komponen: "compiler" dan "interpreter". Penerjemah tidak dapat langsung membaca teks dalam file * .py, jadi teks ini pertama-tama dikonversi menjadi kode byte yang ditargetkan ke PVM (bukan perangkat keras tetapi PVM) . PVM mengeksekusi kode byte ini. * .pyc file juga dihasilkan, sebagai bagian dari menjalankannya yang melakukan operasi impor Anda pada file di shell atau di beberapa file lainnya.
Jika file * .pyc ini sudah dibuat maka setiap kali Anda menjalankan / mengeksekusi file * .py Anda, sistem secara langsung memuat file * .pyc Anda yang tidak memerlukan kompilasi apa pun (Ini akan menghemat beberapa siklus mesin prosesor).
Setelah file * .pyc dibuat, tidak perlu lagi file * .py, kecuali Anda mengeditnya.
sumber
Kode python melewati 2 tahap. Langkah pertama mengkompilasi kode menjadi file .pyc yang sebenarnya merupakan bytecode. Maka file .pyc ini (bytecode) ditafsirkan menggunakan juru bahasa CPython. Silakan merujuk ke tautan ini . Di sini proses kompilasi dan eksekusi kode dijelaskan dengan istilah yang mudah.
sumber