Pertanyaan Jika Python ditafsirkan, apa file .pyc?


Saya telah diberikan untuk memahami bahwa Python adalah bahasa yang ditafsirkan ... Namun, ketika saya melihat kode sumber Python saya yang saya lihat .pyc file, yang diidentifikasi oleh Windows sebagai "File Python Tersusun". Di mana ini masuk?


796
2018-06-08 14:27


asal


Jawaban:


Mereka mengandung kode byte, yang mana interpreter Python mengkompilasi sumbernya. Kode ini kemudian dijalankan oleh mesin virtual Python.

Dokumentasi Python menjelaskan definisi seperti ini:

Python adalah bahasa yang ditafsirkan, sebagai   bertentangan dengan yang dikompilasi, meskipun   perbedaan bisa buram karena   kehadiran kompilator bytecode.   Ini berarti file sumber bisa   berjalan langsung tanpa secara eksplisit   menciptakan eksekutabel yang kemudian   menjalankan.


516
2018-06-08 14:28



Saya telah diberikan untuk memahami hal itu   Python adalah bahasa yang ditafsirkan ...

Meme populer ini tidak benar, atau lebih tepatnya, dibangun di atas kesalahpahaman tentang tingkat bahasa (alami): kesalahan serupa adalah dengan mengatakan "Alkitab adalah buku hardcover". Biar kujelaskan simile itu ...

"The Bible" 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 mendasar (isinya, meskipun itu bisa dalam bahasa yang berbeda, dengan terjemahan yang dapat diterima, tingkat catatan kaki dan penjelasan lainnya) - namun, buku-buku tersebut adalah diizinkan dengan sangat baik untuk berbeda dalam segudang aspek yang tidak dianggap mendasar - jenis pengikatan, warna pengikatan, font (s) yang digunakan dalam pencetakan, ilustrasi jika ada, lebar margin yang dapat ditulis atau tidak, angka dan jenis penanda bawaan, dan seterusnya, dan seterusnya.

Sangat mungkin bahwa a khas pencetakan Alkitab memang akan menjadi pengikatan hardcover - bagaimanapun juga, ini adalah buku yang biasanya dimaksudkan untuk dibaca berulang-ulang, diberi penanda di beberapa tempat, membolak-balik mencari petunjuk bab-dan-ayat yang diberikan, dll, dll, dan pengikatan hardcover yang baik dapat membuat salinan yang diberikan bertahan lebih lama di bawah penggunaan tersebut. 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 bahasa implementasi yang semuanya harus serupa dalam beberapa hal mendasar (sintaksis, sebagian besar semantik kecuali bagian-bagian di mana mereka secara eksplisit diizinkan untuk berbeda) tetapi sepenuhnya diperbolehkan untuk berbeda dalam setiap detail "implementasi" - termasuk bagaimana mereka menangani file sumber yang diberikan, apakah mereka mengkompilasi sumber ke beberapa bentuk tingkat yang lebih rendah (dan, jika demikian, yang membentuk - dan apakah mereka menyimpan formulir yang dikompilasi, ke disk atau tempat lain), bagaimana mereka mengeksekusi bentuk-bentuk kata, dan sebagainya .

Implementasi klasik, CPython, sering disebut hanya "Python" untuk pendek - tapi itu hanya salah satu dari beberapa implementasi kualitas produksi, berdampingan dengan Microsoft's IronPython (yang mengkompilasi kode CLR, yaitu, ".NET"), Jython (yang mengkompilasi kode JVM), PyPy (yang ditulis dengan Python itu sendiri dan dapat dikompilasi ke berbagai macam "back-end" bentuk termasuk bahasa mesin "just-in-time" yang dihasilkan). Mereka semua Python (== "implementasi bahasa Python") sama seperti banyak objek buku yang dangkal berbeda semuanya bisa menjadi Alkitab (== "salinan Alkitab").

Jika Anda tertarik pada CPython secara khusus: ia mengkompilasi file sumber ke dalam bentuk tingkat rendah khusus 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 mengkompilasi ulang mereka di masa mendatang). OTOH IronPython biasanya akan mengkompilasi kode CLR (menyimpannya ke disk atau tidak, tergantung) dan Jython ke kode JVM (menyimpannya ke disk atau tidak - ia akan menggunakan .class ekstensi jika itu menyelamatkan mereka).

Bentuk tingkat yang lebih rendah ini kemudian dieksekusi oleh "mesin virtual" yang tepat yang juga dikenal sebagai "juru bahasa" - CPython VM, runtime .Net, Java VM (alias JVM), yang sesuai.

Jadi, dalam pengertian ini (apa yang dilakukan oleh implementasi khas), Python adalah "bahasa yang ditafsirkan" jika dan hanya jika C # dan Java adalah: semuanya memiliki strategi implementasi yang khas menghasilkan bytecode pertama, kemudian mengeksekusinya melalui VM / interpreter .

Lebih mungkin fokusnya adalah pada bagaimana "berat", lambat, dan tinggi upacara proses kompilasi. CPython dirancang untuk dikompilasi secepat mungkin, seringan mungkin, dengan upacara sesedikit mungkin - kompilator melakukan sangat sedikit pengecekan kesalahan dan optimalisasi, sehingga dapat berjalan cepat dan dalam jumlah kecil memori, yang pada gilirannya memungkinkan dijalankan secara otomatis dan transparan kapan pun diperlukan, tanpa pengguna bahkan perlu menyadari bahwa ada kompilasi yang sedang berlangsung, sebagian besar waktu. Java dan C # biasanya menerima lebih banyak pekerjaan selama kompilasi (dan karena itu tidak melakukan kompilasi otomatis) untuk memeriksa kesalahan lebih teliti dan melakukan lebih banyak pengoptimalan. Ini adalah rangkaian skala abu-abu, bukan situasi hitam atau putih, dan itu akan benar-benar sewenang-wenang untuk menempatkan ambang pada tingkat tertentu dan mengatakan bahwa hanya di atas tingkat itu Anda menyebutnya "kompilasi"!


779
2018-06-08 15:00



Tidak ada yang namanya bahasa yang ditafsirkan. Apakah seorang juru bahasa atau kompiler yang digunakan adalah murni sifat pelaksanaan dan sama sekali tidak ada hubungannya dengan bahasa.

Setiap bahasa dapat diimplementasikan oleh interpreter atau compiler. Sebagian besar bahasa memiliki setidaknya satu implementasi dari setiap jenis. (Sebagai contoh, ada juru bahasa untuk C dan C ++ dan ada kompiler untuk JavaScript, PHP, Perl, Python dan Ruby.) Selain itu, mayoritas implementasi bahasa modern sebenarnya menggabungkan juru bahasa dan kompilator (atau bahkan beberapa kompiler).

Suatu bahasa hanyalah seperangkat aturan matematika abstrak. Interpreter adalah salah satu dari beberapa strategi implementasi konkret untuk suatu bahasa. Keduanya hidup pada tingkat abstraksi yang benar-benar berbeda. Jika bahasa Inggris adalah bahasa yang diketik, istilah "bahasa yang ditafsirkan" akan menjadi kesalahan tipe. Pernyataan "Python adalah bahasa yang ditafsirkan" tidak hanya salah (karena menjadi salah akan menyiratkan bahwa pernyataan itu bahkan masuk akal, bahkan jika itu salah), itu sekadar tidak membuat merasakan, karena suatu bahasa bisa tak pernah didefinisikan sebagai "ditafsirkan."

Khususnya, jika Anda melihat implementasi Python yang saat ini ada, ini adalah strategi implementasi yang mereka gunakan:

  • IronPython: mengkompilasi ke pohon DLR yang DLR kemudian mengkompilasi ke CIL bytecode. Apa yang terjadi pada bycode CIL bergantung pada CLI VES yang Anda jalankan, tetapi Microsoft .NET, GNU Portable.NET dan Novell Mono akhirnya akan mengkompilasinya ke kode mesin asli.
  • Jython: menafsirkan kode sumber Python sampai mengidentifikasi jalur kode panas, yang kemudian dikompilasi ke JVML bytecode. Apa yang terjadi pada JVML bytecode tergantung pada JVM yang Anda jalankan. Maxine akan langsung mengkompilasinya ke kode asli yang tidak dioptimalkan sampai ia mengidentifikasi jalur kode panas, yang kemudian mengkompilasi ulang ke kode asli yang dioptimalkan. HotSpot pertama akan menginterpretasi bytecode JVML dan kemudian akhirnya mengkompilasi jalur kode panas ke kode mesin yang dioptimalkan.
  • PyPy: mengkompilasi ke PyPy bytecode, yang kemudian ditafsirkan oleh VM PyPy sampai mengidentifikasi jalur kode panas yang kemudian dikompilasi menjadi kode asli, JVML bytecode atau bycode CIL tergantung pada platform yang Anda jalankan.
  • CPython: mengkompilasi ke bytecode CPython yang kemudian diinterpretasikan.
  • Stackless Python: mengkompilasi ke bytecode CPython yang kemudian diinterpretasikan.
  • Unladen Swallow: mengkompilasi ke bytecode CPython yang kemudian menafsirkannya sampai mengidentifikasi jalur kode panas yang kemudian dikompilasi ke LLVM IR yang kompiler LLVM kemudian kompilasi ke kode mesin asli.

Anda mungkin memperhatikan bahwa setiap satu dari implementasi dalam daftar itu (ditambah beberapa yang saya tidak sebutkan, seperti tinypy, Shedskin atau Psyco) memiliki kompilator. Bahkan, sejauh yang saya tahu, saat ini tidak ada implementasi Python yang murni ditafsirkan, tidak ada implementasi seperti 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 memberitahumu itu, jelas tidak tahu apa yang dia bicarakan.

Secara khusus, .pyc file yang Anda lihat adalah file bytecode yang di-cache yang dihasilkan oleh CPython, Stackless Python atau Unladen Swallow.


126
2018-06-08 15:25



Ini dibuat oleh interpreter Python ketika a .py file diimpor, dan mereka berisi "bytecode yang dikompilasi" dari modul / program yang diimpor, gagasannya adalah bahwa "terjemahan" dari kode sumber ke bytecode (yang hanya perlu dilakukan sekali) dapat dilewati pada importjika .pyc lebih baru daripada yang terkait .py file, sehingga mempercepat startup sedikit. Tapi itu masih ditafsirkan.


55
2018-06-08 14:30



Python (setidaknya implementasi yang paling umum) mengikuti pola kompilasi sumber asli ke kode byte, kemudian menafsirkan kode byte pada mesin virtual. Ini berarti (sekali lagi, implementasi yang paling umum) bukanlah juru bahasa murni atau compiler murni.

Sisi lain dari ini adalah, bagaimanapun, bahwa proses kompilasi sebagian besar tersembunyi - file .pyc pada dasarnya diperlakukan seperti cache; mereka mempercepat segalanya, tetapi Anda biasanya tidak perlu menyadari mereka sama sekali. Ini secara otomatis membatalkan dan memuat ulang mereka (re-mengkompilasi kode sumber) bila diperlukan berdasarkan waktu file / cap tanggal.

Tentang satu-satunya waktu saya pernah melihat masalah dengan ini adalah ketika file bytecode dikompilasi entah bagaimana mendapat cap waktu ke masa depan, yang berarti selalu tampak lebih baru daripada file sumber. Karena terlihat lebih baru, file sumber tidak pernah dikompilasi ulang, jadi tidak peduli perubahan apa yang Anda buat, mereka diabaikan ...


20
2018-06-08 15:01



INI ADALAH 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 tidak .pyc akan dibuat.

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

Jika Anda perlu membuat file .pyc untuk modul yang tidak diimpor, Anda dapat menggunakan py_compile dan compileall modul.

Itu py_compile modul dapat secara manual mengkompilasi modul apa pun. Salah satu caranya adalah dengan menggunakan py_compile.compile berfungsi dalam modul itu secara interaktif:

>>> import py_compile
>>> py_compile.compile('abc.py')

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.

python -m compileall

Jika nama direktori (direktori saat ini dalam contoh ini) dihilangkan, modul mengkompilasi semua yang ditemukan sys.path


18
2017-11-03 06:47



Untuk mempercepat modul pemuatan, Python menyimpan konten modul yang dikompilasi dalam .pyc.

CPython mengkompilasi kode sumbernya menjadi "kode byte", dan untuk alasan kinerja, ia menyimpan kode byte ini pada sistem file setiap kali file sumber mengalami perubahan. Ini membuat pemuatan modul Python jauh lebih cepat karena fase kompilasi dapat dilewati. Ketika file sumber Anda adalah foo.py, CPython menyimpan 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 ini adalah bagan alur yang menjelaskan cara modul dimuat:

enter image description here

Untuk informasi lebih lanjut:

ref:PEP3147
ref:"Dikompilasi" file Python


16
2017-07-11 17:04



File Python * .py hanyalah sebuah file teks di mana Anda menulis beberapa baris kode. Ketika Anda mencoba untuk mengeksekusi file ini menggunakan katakan "python filename.py"

Perintah ini memanggil Python Virtual Machine. Python Virtual Machine memiliki 2 komponen: "compiler" dan "interpreter". Interpreter tidak dapat langsung membaca teks dalam file * .py, jadi teks ini pertama kali diubah 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 lain.

Jika file * .pyc ini telah dihasilkan, maka setiap kali Anda menjalankan / menjalankan file * .py Anda, sistem akan langsung memuat file * .pyc Anda yang tidak memerlukan kompilasi (Ini akan menghemat siklus mesin prosesor Anda).

Setelah file * .pyc dihasilkan, tidak diperlukan file * .py, kecuali Anda mengeditnya.


9
2017-12-15 06:03



Kode Python melewati 2 tahap. Langkah pertama mengkompilasi kode ke dalam file .pyc yang sebenarnya adalah bytecode. Kemudian file .pyc ini (bytecode) ditafsirkan menggunakan juru bahasa CPython. Silakan lihat ini link. Di sini proses kompilasi dan eksekusi kode dijelaskan dengan mudah.


7
2018-03-26 06:41