Berikut ialah fail kod penuh: Kod
1. Kod Sumber
Apabila anda menulis skrip Python, ia adalah teks yang boleh dibaca manusia. Kod sumber ini adalah titik permulaan untuk segala-galanya.
Kod sumber Python anda, yang ditulis dalam fail .py, boleh dibaca oleh manusia. Kod ini mentakrifkan perkara yang program anda lakukan, menyatakan pembolehubah, fungsi, gelung dan sebagainya.
2. Penyusunan kepada Bytecode (compiler)
Apabila anda menjalankan program Python, langkah pertama ialah menyusun kod sumber kepada bytecode. Ini dilakukan oleh penterjemah Python:
-
Semakan Sintaks: Memastikan tiada ralat sintaks.
-
Kompilasi: Menterjemah kod sumber peringkat tinggi kepada kod bait, perwakilan bebas platform peringkat rendah. Bytecode ini biasanya berada dalam fail .pyc dalam direktori __pycache__.
-
Penyusun: Python menggunakan penterjemah, tetapi ia mula-mula menyusun kod sumber anda ke dalam bentuk peringkat rendah yang dikenali sebagai kod bait.
-
Tokenizing: Pecahkan kod anda kepada kepingan kecil yang dipanggil token (seperti kata kunci, pengendali, pengecam).
-
Penghuraian: Menganalisis token untuk memastikan ia mematuhi peraturan sintaks Python.
-
Graf Aliran Kawalan (CFG): Mewakili semua laluan yang mungkin dilalui melalui atur cara semasa pelaksanaannya.
-
Penjanaan Bytecode: Menukar token yang dihuraikan kepada bytecode, satu set arahan untuk Mesin Maya Python (PVM).
Mari kita mendalami perkara ini.
Python Compiler: Walaupun Python dikenali sebagai bahasa yang ditafsirkan, ia mempunyai langkah penyusunan. Berikut ialah pecahan:
Tokenisasi:
- Pecahkan kod anda kepada kepingan kecil yang dipanggil token (seperti kata kunci, pengendali, pengecam).
-
Kod Sumber: Bermula dengan kod bertulis anda.
-
Tokenizer (Lexer): Ini memecahkan kod sumber kepada kepingan yang lebih kecil dipanggil token, seperti kata kunci (untuk, jika), pengendali ( , -), pengecam (nama pembolehubah) dan literal (seperti nombor atau rentetan) .
-
Penghuraian: Menganalisis token untuk memastikan ia mematuhi peraturan sintaks Python.
-
Analisis Sintaks: Penghurai mengambil token ini dan menyemaknya terhadap peraturan tatabahasa Python.
-
Pokok Parse: Membina struktur pokok daripada token, mewakili struktur tatabahasa kod.
-
Analisis Semantik: Memastikan kod masuk akal dari segi jenis data, skop dan peraturan khusus konteks lain.
-
Graf Aliran Kawalan (CFG): Mewakili semua laluan yang mungkin dilalui melalui atur cara semasa pelaksanaannya.
-
Graf Aliran Kawalan: Mewakili semua kemungkinan laluan yang mungkin diambil melalui kod semasa pelaksanaan.
-
Nod dan Tepi: Setiap nod mewakili blok asas kod dan tepi mewakili aliran kawalan dari satu blok ke blok yang lain.
-
Penjanaan Bytecode: Menukar token yang dihuraikan kepada bytecode, satu set arahan untuk Mesin Maya Python (PVM).
- Kod bait ialah perwakilan tahap rendah yang lebih padat bagi kod sumber anda, dioptimumkan untuk pelaksanaan. Ia bebas platform, bermakna ia boleh dijalankan pada mana-mana sistem dengan PVM yang serasi.
-
Bytecode: Kod yang dihuraikan ditukar kepada bytecode, peringkat rendah, perwakilan bebas platform.
-
Set Arahan: Kod bait ini ialah satu set arahan yang Mesin Maya Python (PVM) boleh laksanakan. Bytecode disimpan dalam fail .pyc dalam direktori __pycache__ untuk mempercepatkan pelaksanaan masa hadapan.
3. Memuatkan Bytecode (Byte code)
Selepas penyusunan, Mesin Maya Python memuatkan kod bait:
-
Membaca daripada Cache: Jika kod bait telah disusun sebelum ini dan tidak berubah, ia dibaca daripada cache (__pycache__). Ini mempercepatkan pelaksanaan dengan melangkau langkah kompilasi.
- Kod bait dimuatkan ke dalam memori, sedia untuk dilaksanakan. Bytecode kemudiannya dilaksanakan oleh PVM, mentafsir arahan untuk melaksanakan tugas program.
4. Pelaksanaan oleh PVM (PVM)
PVM kini mentafsir dan melaksanakan kod bait:
-
Pelaksanaan Arahan: PVM membaca setiap arahan bytecode dan melaksanakannya. Setiap arahan sepadan dengan operasi tertentu, seperti memuatkan nilai, melakukan aritmetik atau memanggil fungsi.
-
Pengurusan Memori: Menguruskan peruntukan dan deallokasi memori untuk pembolehubah dan objek.
Pengurusan Memori dalam Python:
-
Pengiraan Rujukan: Python menjejaki bilangan rujukan yang terdapat pada objek dalam ingatan. Apabila kiraan rujukan menurun kepada sifar, memori yang diduduki oleh objek boleh dituntut semula.
-
Peruntukan Objek: Objek Python (seperti integer, rentetan, senarai) dicipta dalam ingatan apabila kod dijalankan.
-
Pengumpulan Sampah: Python mempunyai pengumpul sampah yang membantu mengurus memori dengan menyamakan kedudukan memori yang tidak lagi digunakan (iaitu, objek dengan kiraan rujukan sifar).
-
Penggabungan Memori: Python menggunakan kumpulan memori untuk memperuntukkan objek kecil dengan lebih cekap. Pengumpulan ini membantu mengurangkan overhed untuk kerap memperuntukkan dan mengagihkan sebahagian kecil memori.
-
Pengoptimuman Memori: Python menggunakan pelbagai pengoptimuman untuk meminimumkan penggunaan memori, seperti:
- PVM melakukan pelbagai pengoptimuman masa jalan untuk meningkatkan kecekapan, seperti kompilasi tepat dalam masa (JIT) dalam beberapa pelaksanaan (seperti PyPy).
- Menggunakan semula integer kecil dan rentetan interned.
- Mengurus struktur data dengan cekap (cth., tupel, senarai, kamus).
Contoh:
-
Caching Bytecode: PVM cache menyusun bytecode untuk mengelakkan penyusunan semula kod sumber setiap kali. Ini mempercepatkan larian berikutnya.
-
Lipatan Malar: Ini melibatkan memudahkan ungkapan malar pada masa penyusunan dan bukannya masa jalan. Contohnya, 3 * 2 mungkin diprakira kepada 6.
Jadi, secara ringkasnya: PVM adalah seperti konduktor orkestra, dengan lancar menukar kod bait menjadi tindakan yang boleh dilaksanakan oleh komputer anda. Perkara yang menarik ialah kod Python, terima kasih kepada PVM, mudah alih dan boleh dijalankan pada platform yang berbeza tanpa pengubahsuaian.
Bagaimanakah kita boleh melihat bytecode dijana atau tidak?
Apabila anda mengimport modul Python, Python menyusun kod sumber ke dalam bytecode dan menyimpannya dalam direktori __pycache__. Ini membantu mempercepatkan import masa hadapan dengan mengelakkan keperluan untuk menyusun semula modul setiap kali ia diimport.
Ini prosesnya:
-
Import Pertama: Apabila anda mula-mula mengimport modul, Python menyusun fail .py ke dalam bytecode.
-
Direktori pycache: Kod bait disimpan dalam direktori __pycache__, dinamakan sesuatu seperti module_name.cpython-312.pyc. # 312 ialah versi Python.
-
Import Seterusnya: Pada import berikutnya, Python menyemak direktori __pycache__ untuk kod bait yang disusun dan menggunakannya jika kod sumber tidak berubah, mempercepatkan proses import.
Contoh:
Kami mempunyai byte.py. Apabila kita mengimport kod daripada hello_world.py selepas pelaksanaan byte.py, kita dapat melihat akan ada direktori __pycache__ dalam folder tertentu itu dan kita boleh melihat fail .pyc:
from hello_world import greet
greet("Byte code")
Salin selepas log masuk
Salin selepas log masuk
Dengan menggunakan py_compile
modul py_compile, yang membolehkan anda menyusun fail sumber Python ke dalam fail bytecode. Ini ialah cara yang berguna untuk mempercepatkan pelaksanaan skrip untuk larian masa hadapan.
Dalam byte.py
import py_compile
py_compile.compile('hello_world.py')
Salin selepas log masuk
Salin selepas log masuk
- Modul py_compile menyusun hello_world.py ke dalam bytecode.
- Kod bait yang terhasil disimpan dalam direktori pycache, mencipta fail bernama hello_world.cpython-38.pyc (atau serupa, bergantung pada versi Python anda).
Menjana Bytecode:
- Seluruh skrip dilaksanakan untuk menjana kod bait. Ini bermakna sebarang kod peringkat teratas (seperti print("Hello, World!") dan print("c")) akan dijalankan semasa proses penyusunan.
Bytecode yang terhasil:
- Kod bait mengandungi semua fungsi, kelas dan penyataan boleh laku, yang digunakan oleh Python untuk mempercepatkan import skrip pada masa hadapan.
modul dis
Modul dis dalam Python digunakan untuk membuka kod bait ke dalam bentuk yang lebih mudah dibaca. Ini boleh membantu anda memahami perkara yang dilakukan oleh kod Python anda di bawah hud. Ia amat berguna untuk menyahpepijat atau mempelajari tentang dalaman Python.
- Dalam internal.py kita ada
from hello_world import greet
greet("Byte code")
Salin selepas log masuk
Salin selepas log masuk
keluaran
import py_compile
py_compile.compile('hello_world.py')
Salin selepas log masuk
Salin selepas log masuk
- Atur cara bermula dengan mengimport modul dis, alat yang berkuasa untuk menganalisis kod bait CPython. CPython ialah pelaksanaan lalai Python dan bytecode ialah bahasa perantaraan untuk penterjemah Python.
- Seterusnya, saya telah menentukan fungsi mudah yang dipanggil salam. Fungsi ini mengambil nama parameter dan mencetak ucapan. Walaupun fungsi itu sendiri agak mudah, apa yang berlaku di bawah hud dalam Python adalah lebih rumit daripada yang kelihatan di permukaan.
- Fungsi disassemble_function menggunakan dis.dis() untuk membuka fungsi salam. dis.dis() menterjemahkan fungsi Python ke dalam bytecode peringkat rendah yang sebenarnya dilaksanakan oleh mesin maya Python. Bytecode ini ialah tafsiran Python tentang fungsi salam kami dan selangkah lebih dekat dengan kod mesin.
- Apabila skrip memanggil disassemble_function(), output konsol membentangkan bytecode fungsi salam kami.
Berikut ialah perkara yang diberitahu oleh kod bait kepada kami:
- LOAD_GLOBAL(0): opcode ini digunakan untuk memuatkan pembolehubah global, yang, dalam kes ini, ialah fungsi cetakan.
- LOAD_CONST(1): Ini memuatkan nilai malar 'Hello,' ke dalam tindanan.
- LOAD_FAST(0): opcode ini memuatkan nama pembolehubah setempat ke dalam tindanan.
- FORMAT_VALUE(0): Ini memformat rentetan nama kita, menyediakannya untuk dimasukkan ke dalam rentetan yang akan dibina.
- BUILD_STRING(2): Ini mengambil dua nilai teratas pada tindanan ('Hello, ' dan nama) dan membina rentetan akhir.
- CALL_FUNCTION(1): Baris ini memanggil fungsi (fungsi cetakan global yang kami muatkan pada tindanan), dengan kiraan argumen dalam kurungan (kami mempunyai satu argumen, rentetan terformat kami).
- POP_TOP: Ini mengalih keluar bahagian atas tindanan (hasil panggilan sebelumnya, kerana cetakan tidak mengembalikan Tiada).
- LOAD_CONST(0): Tidak Muatkan.
- RETURN_VALUE: Ini ialah nilai pulangan bagi fungsi salam, yang, memandangkan tiada pernyataan pulangan yang jelas, adalah Tiada.
- Pada dasarnya, bytecode menunjukkan operasi individu yang Python lakukan untuk melaksanakan fungsi salam kami. Memahami arahan ini adalah penting untuk pembangun memahami cara Python melaksanakan kod, mengoptimumkan fungsi dan mengurus sumber—semua ini berlaku dengan lancar di bawah hud apabila kami menjalankan kod Python kami.
Bukankah itu menyelam yang menyeronokkan ke dalam bilik mesin Python? Teruskan pengekodan dan teruskan menerokai kedalaman ruang enjin bahasa ini?!
Atas ialah kandungan terperinci Kerja Dalaman Python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!