Python का प्रीप्रोसेसर
(pydong.org)Python का प्रीप्रोसेसर
- यह दावा सही नहीं है कि Python में प्रीप्रोसेसर नहीं होता
- Python में एक बहुत शक्तिशाली प्रीप्रोसेसर होता है
Python source code encoding
- PEP-0263 की बदौलत source code encoding को परिभाषित किया जा सकता है
- पहली दो लाइनों में magic comment जोड़कर encoding सेट की जा सकती है
- उदाहरण:
# coding=utf8,# -*- coding: utf8 -*-,# vim: set fileencoding=utf8 :
path configuration files (.pth)
- जब Python interpreter
-Soption के बिना शुरू होता है, तो वहsitepackage को अपने आप load करता है site-packagesfolder में.pthfile जोड़कर module search path को बढ़ाया जा सकता है.pthfile मेंimportसे शुरू होने वाली lines execute की जाती हैं- इससे Python interpreter initialization के समय मनचाहा code चलाया जा सकता है
custom codec की परिभाषा
- Python interpreter की दो ज़रूरतें पूरी करनी होती हैं:
decode(data: bytes) -> tuple[str, int]function- incremental decoder class
- असली decoding करने के लिए
codecs.utf_8_decodeका उपयोग करें, और result string को प्रीप्रोसेसर तक पहुँचाएँ - exception को पकड़कर print करना और फिर दोबारा raise करना बेहतर है
incremental decoder उपलब्ध कराना
codecs.BufferedIncrementalDecoderinherit करके incremental decoder implement करें- buffer में data इकट्ठा करें और final decode call पर पूरी file को preprocess करें
Python का विस्तार
- Python की standard library का उपयोग करके Python का विस्तार करना अपेक्षाकृत आसान है
tokenizemodule का उपयोग करके file की token stream बदली जा सकती है याastmodule का उपयोग करके abstract syntax tree को बदला जा सकता है
unary increment और decrement
- Python में unary increment और decrement operator नहीं हैं
x++,x--valid नहीं हैं++x,--xvalid हैं, लेकिन उनका अर्थ अलग होता है- unary increment और decrement expressions को Python expressions में बदला जा सकता है
उदाहरण
- input file
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:
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")
braces का उपयोग करने वाला Python (Bython)
- Python की indentation के बजाय braces का उपयोग करके scope तय किया जा सकता है
- token stream को बदलने के लिए
tokenize.generate_tokensका उपयोग करें
उदाहरण
- input file
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:
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()})
दूसरी भाषाओं की व्याख्या
- Python interpreter को दूसरी भाषाओं की व्याख्या करने के लिए भी इस्तेमाल किया जा सकता है
- उदाहरण: C, C++, TOML
उदाहरण
- C++ file
test.cpp:#define CODEC "coding:magic.cpp" #include <cstdio> int main() { puts("Hello World"); } - बदली हुई file:
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()
data validation
- TOML format के data को JSON schema का उपयोग करके validate किया जा सकता है
- असली validation के लिए
jsonschemaका उपयोग करें
उदाहरण
- schema file
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"] } } } - valid data file
data_valid.toml:# coding: magic.toml name = "John Doe" age = 42 scores = [40, 20, 80, 90] [address] street = "Grove St. 4" postcode = 19201 - invalid data file
data_invalid.toml:# coding: magic.toml name = "John Doe" age = 42 scores = [40, "20", 80, 90] [address] street = "Grove St. 4" postcode = 19201
निष्कर्ष
- custom codec और path configuration file का उपयोग करके Python interpreter के व्यवहार को काफी हद तक बदला जा सकता है
- उदाहरण के तौर पर
pythonql,future-typing,future-fstrings,future-annotationsआदि हैं magic_codecका उपयोग करके अपना प्रीप्रोसेसर आसानी से प्रयोगात्मक रूप से बनाया जा सकता है
GN⁺ का सार
- Python के प्रीप्रोसेसर का उपयोग करके अलग-अलग language extension और data validation किए जा सकते हैं
- यह समझाया गया है कि custom codec के माध्यम से Python interpreter के व्यवहार को कैसे बदला जा सकता है
- यह लेख Python developers के लिए उपयोगी tools और techniques प्रदान करता है
- मिलती-जुलती functionality वाले projects में
pythonql,future-typingआदि शामिल हैं
1 टिप्पणियां
Hacker News राय
from __future__ import bracesका syntax error message 2001 से cpython में hardcoded हैimport-hooks का उपयोग करके किसी को निकालने के रचनात्मक तरीकों के बारे में सोचा था, लेकिन यह अफसोस रहा कि codec regex
"μtf8"जैसी चीज़ इस्तेमाल नहीं करने देताsys.settraceका इस्तेमाल करके हर function को उससे पहले कॉल किए गए function से monkey patch करना होगा, और हर 17 मिनट में stdout और stderr को आपस में बदलना होगाकोई वजह है कि python preprocessor hooks expose नहीं करता, और मुझे लगता है कि समझदार वयस्कों को इससे बचना चाहिए
preprocessor ज़्यादा सुविधाजनक और उपयोगी है
astmodule का इस्तेमाल करके code rewrite किया, उसेexecसे चलाया, और फिरexit()insert करके hack कियाastrewriting feature का उपयोग काफ़ी काम की चीज़ के रूप में किया थामुझे python की flexibility बहुत पसंद है
mmapका दुरुपयोग करके script को खुद को modify करने पर मजबूर कियाpyxlका उपयोग करने का सबसे अच्छा उदाहरण JSX से प्रेरित है# coding: pyxlका इस्तेमाल करके HTML code लिखा जा सकता हैसोचता हूँ कि Python 2 से 3 में transition को क्या बेहतर ढंग से संभाला जा सकता था
# coding: six.python2Python2 code को Python3 में valid बना सकता है, और# coding: six.python3Python3 code को Python2 में runnable बनाने के लिए adjust कर सकता हैअच्छा लगा कि तुम्हें यह idea पसंद आया, जल्द ही और सामग्री आने वाली है
बहुत समय बाद किसी पूरी तरह नए idea पर हैरानी महसूस हुई
अगर Python में inline code generation चाहिए, तो Ned Batchelder का cog इस्तेमाल कर सकते हैं
सोच रहा हूँ कि इस coding hook strategy से लाई गई dependencies को
pip freezeया uv detect करते हैं या नहीं