Preprosesor Python
(pydong.org)Preprosesor Python
- Anggapan bahwa Python tidak memiliki preprosesor sebenarnya tidak benar
- Python memiliki preprosesor yang sangat kuat
Encoding kode sumber Python
- Berkat PEP-0263, encoding kode sumber dapat didefinisikan
- Encoding dapat diatur dengan menambahkan magic comment pada dua baris pertama
- Contoh:
# coding=utf8,# -*- coding: utf8 -*-,# vim: set fileencoding=utf8 :
File konfigurasi path (.pth)
- Saat interpreter Python dijalankan tanpa opsi
-S, paketsitedimuat secara otomatis - Jalur pencarian modul dapat diperluas dengan menambahkan file
.pthke foldersite-packages - Baris dalam file
.pthyang dimulai denganimportakan dieksekusi - Ini memungkinkan eksekusi kode arbitrer saat inisialisasi interpreter Python
Mendefinisikan codec kustom
- Ada dua kebutuhan yang harus dipenuhi oleh interpreter Python:
- fungsi
decode(data: bytes) -> tuple[str, int] - kelas decoder inkremental
- fungsi
- Gunakan
codecs.utf_8_decodeuntuk melakukan decoding sebenarnya, lalu teruskan string hasilnya ke preprosesor - Sebaiknya tangkap exception, tampilkan, lalu lemparkan kembali
Menyediakan decoder inkremental
- Implementasikan decoder inkremental dengan mewarisi
codecs.BufferedIncrementalDecoder - Kumpulkan data di buffer dan lakukan praproses seluruh file saat pemanggilan decode final
Ekstensi Python
- Memperluas Python dengan menggunakan pustaka standar Python relatif mudah
- Anda dapat memodifikasi stream token file dengan modul
tokenizeatau memodifikasi abstract syntax tree dengan modulast
Increment dan decrement unary
- Python tidak memiliki operator increment dan decrement unary
x++,x--tidak valid++x,--xvalid tetapi memiliki makna yang berbeda- Ekspresi increment dan decrement unary dapat diubah menjadi ekspresi Python
Contoh
- File input
incdec.py:# coding: magic.incdec i = 6 assert i-- == 6 assert i == 5 assert ++i == 6 assert --i == 5 assert i++ == 5 assert i == 6 assert (++i, 'i++') == (7, 'i++') print("PASSED") - File hasil transformasi:
i = 6 assert ((i, i := i - 1)[0]) == 6 assert i == 5 assert ((i, i := i + 1)[1]) == 6 assert ((i, i := i - 1)[1]) == 5 assert ((i, i := i + 1)[0]) == 5 assert i == 6 assert (((i, i := i + 1)[1]), 'i++') == (7, 'i++') print("PASSED")
Python dengan kurung kurawal (Bython)
- Cakupan dapat ditentukan dengan kurung kurawal alih-alih indentasi Python
- Stream token dimodifikasi menggunakan
tokenize.generate_tokens
Contoh
- File input
test.by:# coding: magic.braces def print_message(num_of_times) { for i in range(num_of_times) { print("braces ftw") } print({'x': 3}) } x = { 'foo': 42, 'bar': 5 } if __name__ == "__main__" { print_message(2) print({k: v for k, v in x.items()}) } - File hasil transformasi:
def print_message(num_of_times): for i in range(num_of_times): print("braces ftw") print({'x': 3}) x = { 'foo': 42, 'bar': 5 } if __name__ == "__main__": print_message(2) print({k: v for k, v in x.items()})
Menginterpretasikan bahasa lain
- Interpreter Python dapat dibuat untuk menginterpretasikan bahasa lain
- Contoh: C, C++, TOML
Contoh
- File C++
test.cpp:#define CODEC "coding:magic.cpp" #include <cstdio> int main() { puts("Hello World"); } - File hasil transformasi:
import cppyy cppyy.cppdef(r""" #define CODEC "coding:magic.cpp" #include <cstdio> int main() { puts("Hello World"); } """) from cppyy.gbl import main if __name__ == "__main__": main()
Validasi data
- Data berformat TOML dapat divalidasi menggunakan skema JSON
jsonschemadigunakan untuk melakukan validasi sebenarnya
Contoh
- File skema
schema.json:{ "type": "object", "properties": { "name": {"type": "string"}, "age": {"type": "number"}, "scores": { "type": "array", "items": {"type": "number"} }, "address": {"$ref": "#/$defs/address"} }, "required": ["name"], "$defs": { "address": { "type": "object", "properties": { "street": {"type": "string"}, "postcode": {"type": "number"} }, "required": ["street"] } } } - File data valid
data_valid.toml:# coding: magic.toml name = "John Doe" age = 42 scores = [40, 20, 80, 90] [address] street = "Grove St. 4" postcode = 19201 - File data tidak valid
data_invalid.toml:# coding: magic.toml name = "John Doe" age = 42 scores = [40, "20", 80, 90] [address] street = "Grove St. 4" postcode = 19201
Kesimpulan
- Dengan menggunakan codec kustom dan file konfigurasi path, perilaku interpreter Python dapat diubah secara signifikan
- Contohnya termasuk
pythonql,future-typing,future-fstrings,future-annotations, dan lainnya - Anda dapat dengan mudah bereksperimen dengan preprosesor sendiri menggunakan
magic_codec
Ringkasan GN⁺
- Berbagai ekstensi bahasa dan validasi data dapat dilakukan dengan memanfaatkan preprosesor Python
- Dijelaskan cara mengubah perilaku interpreter Python melalui codec kustom
- Artikel ini menyediakan alat dan teknik yang berguna bagi pengembang Python
- Proyek dengan fungsi serupa antara lain
pythonql,future-typing, dan lainnya
1 komentar
Komentar Hacker News
pesan galat sintaks
from __future__ import bracestelah di-hardcode di cpython sejak 2001sempat memikirkan cara pemecatan yang kreatif dengan menggunakan import-hooks, tetapi sayang codec regex mencegah penggunaan sesuatu seperti "μtf8"
ada alasan mengapa python tidak mengekspos hook preprocessor, dan saya rasa orang dewasa yang rasional sebaiknya menghindarinya
preprocessor lebih praktis dan berguna
saya suka fleksibilitas python
contoh terbaik penggunaan pyxl terinspirasi dari jsx
# coding: pyxl, kita bisa menulis kode HTMLbertanya-tanya apakah transisi dari Python 2 ke 3 bisa ditangani dengan lebih baik
# coding: six.python2bisa membuat kode Python2 menjadi valid di Python3, dan# coding: six.python3bisa menyesuaikan kode Python3 agar dapat dijalankan di Python2senang ide ini disukai, akan ada lebih banyak lagi segera
sudah lama sekali sejak terakhir kali merasa takjub oleh ide yang benar-benar baru
jika ingin pembuatan kode inline di Python, Anda bisa memakai cog buatan Ned Batchelder
penasaran apakah dependensi yang diperkenalkan lewat strategi coding hook ini terdeteksi oleh
pip freezeatau uv