Saya memahami bahwa file ".pyc" adalah versi yang dikompilasi dari file teks biasa ".py", yang dibuat pada waktu proses untuk membuat program berjalan lebih cepat. Namun saya telah mengamati beberapa hal:
- Setelah modifikasi file "py", perilaku program berubah. Hal ini menunjukkan bahwa file "py" telah dikompilasi atau setidaknya melalui proses hashing atau membandingkan stempel waktu untuk mengetahui apakah file tersebut harus dikompilasi ulang atau tidak.
- Setelah menghapus semua file ".pyc" (
rm *.pyc
) terkadang perilaku program akan berubah. Yang menunjukkan bahwa mereka tidak dikompilasi pada pembaruan ".py".
Pertanyaan:
- Bagaimana mereka memutuskan kapan akan dikompilasi?
- Adakah cara untuk memastikan bahwa mereka memiliki pemeriksaan yang lebih ketat selama pengembangan?
python
python-internals
pyc
Aaron Schif
sumber
sumber
rm *.pyc
. Ini tidak akan menghapus file .pyc dalam folder bersarang. Gunakanfind . -name '*.pyc' -delete
sebagai gantinyaJawaban:
The
.pyc
file diciptakan (dan mungkin ditimpa) hanya ketika file python diimpor oleh beberapa script lainnya. Jika impor dipanggil, Python memeriksa untuk melihat apakah.pyc
stempel waktu internal file tidak lebih lama dari.py
file yang sesuai . Jika ya, itu memuat.pyc
; jika tidak atau jika.pyc
belum ada, Python mengkompilasi.py
file menjadi a.pyc
dan memuatnya.Apa yang Anda maksud dengan "pemeriksaan yang lebih ketat"?
sumber
rm *.pyc
. Saya tahu bahwa jika saya memaksa semua file untuk dibuat ulang, maka beberapa masalah telah diperbaiki, yang menunjukkan bahwa file tidak dikompilasi ulang sendiri. Saya kira jika mereka menggunakan stempel waktu maka tidak ada cara untuk membuat perilaku ini lebih ketat, tetapi masalahnya masih berlanjut..pyc
's timestamp harus lebih tua dari yang sesuai.py
' s timestamp untuk memicu kompilasi ulang sebuah.File .pyc dibuat setiap kali elemen kode yang sesuai diimpor, dan diperbarui jika file kode terkait telah diperbarui. Jika file .pyc dihapus, mereka akan dibuat ulang secara otomatis. Namun, mereka tidak secara otomatis dihapus ketika file kode terkait dihapus.
Ini dapat menyebabkan beberapa bug yang sangat menyenangkan selama refactors tingkat file.
Pertama-tama, Anda dapat mendorong kode yang hanya berfungsi pada mesin Anda dan tidak pada mesin orang lain. Jika Anda memiliki referensi yang menggantung ke file yang Anda hapus, ini akan tetap berfungsi secara lokal jika Anda tidak menghapus file .pyc yang relevan secara manual karena file .pyc dapat digunakan dalam impor. Ini ditambah dengan fakta bahwa sistem kontrol versi yang dikonfigurasi dengan benar hanya akan mendorong file .py ke repositori pusat, bukan file .pyc, yang berarti bahwa kode Anda dapat lulus "uji impor" (melakukan impor semuanya dengan baik) dengan baik dan tidak bekerja di komputer orang lain.
Kedua, Anda dapat memiliki beberapa bug yang cukup parah jika Anda mengubah paket menjadi modul. Saat Anda mengonversi paket (folder dengan
__init__.py
file) menjadi modul (file .py), file .pyc yang pernah mewakili paket itu tetap ada. Secara khusus,__init__.pyc
sisa - sisa. Jadi, jika Anda memiliki paket foo dengan beberapa kode yang tidak masalah, kemudian hapus paket itu dan buat file foo.py dengan beberapa fungsidef bar(): pass
dan jalankan:from foo import bar
Anda mendapatkan:
ImportError: cannot import name bar
karena python masih menggunakan file .pyc lama dari paket foo, tidak ada yang mendefinisikan bilah. Hal ini dapat menjadi masalah terutama pada server web, di mana kode yang berfungsi total dapat rusak karena file .pyc.
Sebagai hasil dari kedua alasan ini (dan mungkin yang lainnya), kode penerapan dan kode pengujian Anda harus menghapus file .pyc, seperti dengan baris bash berikut:
find . -name '*.pyc' -delete
Selain itu, pada python 2.6, Anda dapat menjalankan python dengan
-B
flag untuk tidak menggunakan file .pyc. Lihat Bagaimana cara menghindari file .pyc? untuk lebih jelasnya.Lihat juga: Bagaimana cara menghapus semua file .pyc dari sebuah proyek?
sumber
__init__.py
file) ...". Itu akan menjadi sebuah paket, bukan modul.__init__.pyc
sisa - sisa. - Bagaimana bisa? Karena paket adalah direktori, menghapus paket berarti menghapus direktori sehingga tidak ada file yang tersisa….pyc
Masalah ini adalah salah satu alasannya, juga: ketergantungan tersembunyi pada OS dan tingkat tambalan utilitas,.so
file , file konfigurasi, libs Python lainnya (jika Anda tidak menjalankan virtual env), mengaburkan env vars ... daftarnya terus berlanjut. Untuk teliti dan menemukan semua masalah seperti itu, Anda perlu membuat salinan bersih kode Anda di repo git atau menerbitkan sebagai paket ke server gaya PyPi, dan melakukan klon penuh atau penyiapan pada VM baru. Beberapa dari masalah potensial tersebut membuat masalah ini menjadi.pyc
pucat jika dibandingkan.