- हाल की AI development ट्रेंड के कारण मैंने गंभीरता से Python सीखना और इस्तेमाल करना शुरू किया, और अब उसके ecosystem से काफी संतुष्टि महसूस कर रहा हूँ
- Python पहले की तुलना में कहीं ज़्यादा तेज़ और आधुनिक भाषा बन चुका है, और Cython के जरिए performance improvement जैसी तेज़ प्रगति को प्रत्यक्ष महसूस किया है
- uv, ruff, pytest, Pydantic जैसे आधुनिक development tools और libraries को अपने workflow में सक्रिय रूप से अपनाकर development productivity बढ़ा रहा हूँ
- production environment और Jupyter notebook/स्क्रिप्ट-आधारित development के बीच का अंतर कम करने के लिए project structure और automation के तरीके भी लागू किए हैं
- GitHub Actions, Docker आदि का उपयोग करके CI/CD, testing, infrastructure management को प्रभावी ढंग से स्थापित किया है
I’m Switching to Python and Actually Liking It सारांश
मैंने Python की ओर स्विच क्यों किया
- AI-केंद्रित development environment में Python de facto standard language के रूप में स्थापित हो चुका है
- पहले इसे केवल साधारण scripts लिखने के लिए इस्तेमाल करता था, लेकिन हाल में RAG, agent, generative AI जैसे “production-grade apps” बनाने के लिए इसे गंभीरता से उपयोग करने लगा हूँ
- इस प्रक्रिया में महसूस हुआ कि Python ecosystem अतीत की तुलना में काफी विकसित हो चुका है
Python की 3 ताकतें
- समृद्ध library और tool ecosystem: data processing, analysis, web, AI के लिए विशेष रूप से मजबूत
- Cython आदि के कारण performance improvement: compile-आधारित optimization संभव
- बेहतर syntax readability:
__init__, __new__ जैसी legacy syntax अब छिप जाती है, और अधिक सहज syntax मिलता है
project structure (Monorepo आधारित)
मुख्य tools और settings
-
uv
- Astral द्वारा प्रदान किया गया आधुनिक Python package manager और build tool
- dependency management, virtual environment creation, project initialization जैसे अधिकांश काम तेज़ी से करता है
pyproject.toml मुख्य configuration file है, जिसमें सभी metadata और dependency information एकीकृत रहती है
uv init, uv add, uv sync commands से project environment जल्दी तैयार किया जा सकता है
-
ruff
- अत्यंत तेज़ Python linter और code formatter
isort, flake8, autoflake आदि को एकीकृत करने वाला tool
ruff check, ruff format से linting और auto-fix
- PEP 8 coding style guide का default support
-
ty
- Astral द्वारा बनाया गया Python का static type checker
typing के साथ मिलकर static analysis और शुरुआती bugs की रोकथाम में प्रभावी
- शुरुआती development stage में होने के बावजूद इस्तेमाल के लिए पर्याप्त स्थिर
-
pytest
- unit testing और extensible test environment देने वाला प्रमुख Python testing framework
- सरल file naming rules और एक command से तुरंत integration testing संभव
test_*.py के रूप में tests लिखकर uv run pytest से चलाया जा सकता है
- concise syntax, समृद्ध plugin ecosystem
-
Pydantic
- data validation और environment settings management library
.env environment variables-आधारित settings loading और type validation
BaseSettings class के जरिए API key या DB URL जैसी चीज़ों को सुरक्षित ढंग से manage किया जा सकता है
-
MkDocs
- Python projects के लिए static website और documentation generation को आसानी से support करता है
- open source project शैली का आकर्षक design जल्दी लागू किया जा सकता है
- GitHub Pages integration भी आसान है
-
FastAPI
- तेज़ RESTful API निर्माण framework
- automatic validation और documentation, तेज़ performance, आसान Pydantic integration इसके फायदे हैं
- Starlette और Pydantic पर आधारित होकर उच्च type safety और performance देता है
-
Dataclasses
- Python की standard feature के रूप में data-centric classes को आसानी से define किया जा सकता है
- special methods के automatic generation से boilerplate code में बड़ी कमी आती है
version control और automation
-
GitHub Actions
project-api और project-ui के लिए अलग-अलग CI pipelines बनाई गई हैं
- विभिन्न OS पर CI pipelines बनाने के लिए अनुकूल workflow प्रदान करता है
- Docker-आधारित test environment से production जैसे ही environment में testing संभव है
-
Dependabot
- automatic dependency updates और security patch management को automate करता है
-
Gitleaks
- sensitive information (password, API key आदि) के leak को रोकने वाला tool, जो git commit से पहले security checks करता है
-
Pre-commit Hooks
- commit से पहले automatic linting, formatting, security checks के लिए tool
- ruff, gitleaks आदि के साथ उपयोग कर code consistency और quality बनाए रखता है
infrastructure automation
-
Make
make test, make infrastructure-up जैसे commands से consistent development workflow मिलता है
- project root और
project-api में अलग-अलग Makefile मौजूद हैं
-
Docker & Docker Compose
project-api, project-ui को अलग-अलग containers में चलाया जाता है
docker compose up --build -d की एक पंक्ति से पूरा app चलाया जा सकता है
Dockerfile में uv installation और FastAPI app run command शामिल है
निष्कर्ष
- इस तरह आधुनिक Python development environment में एक प्रभावी और मजबूत production workflow बनाया जा सकता है
- AI, data, web development जैसे कई क्षेत्रों में Python ecosystem की growth और tools की प्रगति से बहुत लाभ लिया जा सकता है
- monorepo structure, automation tools, linter और type checker, त्वरित test environment, documentation, और infrastructure orchestration तक एकीकृत development culture लागू किया जा सकता है
6 टिप्पणियां
Python में switch कर रहा हूँ, और उम्मीद से कहीं ज़्यादा पसंद आ रहा है
Python में libraries और frameworks भरपूर हैं, लेकिन package version management अच्छी नहीं है और conflicts अक्सर होते हैं, यह इसकी कमी है.
पुराने Java की तरह इसके भी फायदे-नुकसान का रुझान काफ़ी मिलता-जुलता है
लेख में आया
uvवाकई कमाल की चीज़ है। यह तेज़ भी है, और version व dependency management भी npm की तरह अच्छी तरह कर देता है, इसलिए मैंuvपर टिक गया हूँ।फिर भी, आजकल लगता है कि
uvऔरpoetryकी मदद से version management और conflicts ज़्यादातर हद तक सुलझ गए हैं।क्या React और ऐसे हिस्सों तक ecosystem को समेटने के लिए भी यह उपयुक्त है?
React के साथ सीधे इंटीग्रेशन करना, क्योंकि भाषा अलग है, कुछ मामलों में मुश्किल हो सकता है, लेकिन आप क्या चाहते हैं उस पर निर्भर करते हुए कुछ चीज़ें संभव भी लगती हैं.
व्यक्तिगत रूप से, मुझे लगता है कि Python के जरिए फ्रंटएंड डेवलपमेंट अभी बहुत ज़्यादा सक्रिय क्षेत्र नहीं है.
Hacker News राय
अगर code में environment variable गायब हो तो “YOUTUBE_API_KEY या YOUTUBE_CHANNEL_ID नहीं है” जैसा OR वाला message दिखाना, ऐसी स्थिति में जहाँ OR की ज़रूरत ही नहीं है, user को बेवजह परेशान करता है। हर value को अलग-अलग check करके साफ़ बताना कि क्या missing है, कहीं बेहतर user experience है। development time में भी लगभग कोई फ़र्क नहीं पड़ता, इसलिए मैं यही करने की सलाह दूँगा
यह थोड़ा बारीकी में जाने जैसा है, लेकिन मुझे लगता है कि ऐसे case में := operator (walrus operator) बिल्कुल सही बैठता है। उदाहरण के लिए,
if not (API_KEY := os.getenv("API_KEY")):की तरह सीधे इस्तेमाल किया जा सकता है। निजी तौर पर, internal tools में मैंos.environ["API_KEY"]परKeyErrorको वैसे ही आने देता हूँ। मुझे यह भी काफ़ी स्पष्ट लगता हैइससे आगे बढ़कर, conditions को एक-एक करके check करना और अगर एक भी missing हो तो सब कुछ एक साथ बताना कहीं बेहतर है। इससे वह झंझट कम होता है कि एक variable missing होने पर program चलाओ, फिर अगली बार दूसरा variable error देखो। कुछ situations में यह अनिवार्य रूप से झंझटभरा हो सकता है, लेकिन जहाँ संभव हो, सब कुछ एक बार में दिखाना बेहतर है
सभी environment variables को fetch करके, उनमें जो missing हैं उन्हें एक साथ report करना सबसे अच्छा तरीका है
boolean flag का इस्तेमाल करके अंत में सिर्फ़ एक बार
exit(1)करने का तरीका भी है। इससे missing environment variables एक साथ दिखाए जा सकते हैंexit("Missing ...")की तरह message सीधे print करते हुए code 1 के साथ exit भी कर सकते हैंअगर आप project structure अपने-आप बनाने वाला tool ढूँढ़ रहे हैं, तो
cookiecutterकी सिफारिश करूँगा। मेरे कुछ templates हैं जिन्हें मैं अक्सर इस्तेमाल करता हूँ, जैसे python-lib, click-app, datasette-plugin, llm-plugin। इसे इस तरह इस्तेमाल कर सकते हैं:uvx cookiecutter gh:simonw/python-libमैंने Ruby में
bakerनाम की चीज़ बनाई थी। baker template repo को copy नहीं करता, बल्कि करने वाले कामों की checklist (imperative steps की list) बनाता है, और manual tasks (API key लाकर set करना) को automated tasks (uv initवगैरह) के साथ मिला सकता है। इसमें Markdown syntax के साथ Ruby string interpolation और bash भी इस्तेमाल कर सकते हैं। yml-based config से बहुत थक गया था, इसलिए इसे बनायाआजकल जो tool चर्चा में है, वह
Copierहै। ज़्यादा जानकारी के लिए copier docs देखेंमुझे तो नया project set up करना उल्टा अच्छा लगता है। मैं ऐसी चीज़ों को ज़बरदस्ती automate नहीं करना चाहता
सच कहूँ तो, इस तरह के structuring automation tools आजकल agent-based LLM development workflow के लिए भी बिल्कुल सही क्षेत्र लगते हैं
"Python ज़्यादातर Unix systems में default रूप से आता है, इसलिए ज़्यादा human-friendly है" — यह आकलन थोड़ा ज़्यादा आशावादी है।
import jsonसे आगे जाते ही बहुत जल्दी virtualenv की मुश्किलों में फँस जाते हैं। Python 3.13.x environment में Ubuntu 22.04 या 24.04, Rocky 9 वगैरह पर चलाना हो, तो आखिरकारvenv, container, या version manager ज़रूरी हो ही जाते हैंimport jsonजैसी basic library भी, अगर language में built-in न हो, तो अलग से install करनी पड़ती है; लेकिन Python standard library की वजह से शुरुआती productivity kाफ़ी ऊँची रहती है। मान लिया कि बड़े projects में सिर्फ़ standard library काफ़ी नहीं होती, लेकिन मैंने वास्तव में सिर्फ़ standard library से कई production-grade code deploy किए हैं और deployment या security management की कोई दिक्कत नहीं आई।venvmanagement भी पहले जितना मुश्किल नहीं रहा, और package managers भी बेहतर हुए हैंमेरा एक आधा-मज़ाकिया सिद्धांत है कि Docker/containers इतनी जल्दी लोकप्रिय होने की आधी वजह यह थी कि उन्होंने Python dependency hell से राहत दी। Python के साथ मेरा पहला अनुभव 2012 में server पर Python service install करना था, और dependency hell,
venvcommands, मुश्किल environment setup — सब बहुत भयानक था।pip,brew, macOS environment — हर जगह सिर्फ़ जूझना ही पड़ा, और Python दिखते ही उससे बचता था। लेकिन हाल मेंuvकी वजह से शुरुआती users के लिए भी Python काफ़ी बेहतर लगा।uv init,uv add,uv runसे ही काम चल जाता हैमुझे लगता है
virtualenvहमेशा इस्तेमाल करना चाहिए। आख़िरकार यह सिर्फ़ एक directory ही है, और अब अगरpipसे system-wide install करने की कोशिश करें तो warning भी मिलती है, इसलिए यह पहले जितना मुश्किल नहीं हैvirtualenvया container ज़रूर इस्तेमाल करना अच्छा है। चाहे संभालना थोड़ा मुश्किल लगे, लेकिन इससे updates या library version upgrades की वजह से पूरे system पर असर पड़ने से बचते हैंपहले अक्सर system में सिर्फ़ Python2 default रूप से होता था, और कभी-कभी system खुद उसी Python2 पर निर्भर भी होता था, इसलिए वह और भी जोखिमभरा था
मुझे Python एक साथ verbose भी लगता है और अधूरा भी। कुछ simple करना हो तो या तो 500 dependencies जोड़नी पड़ती हैं, या फिर बहुत मामूली काम के लिए भी दर्जनों से लेकर सैकड़ों lines तक code बढ़ जाता है। इसलिए Python में बेकार की माथापच्ची बहुत ज़्यादा लगती है और मैं उससे बचता हूँ। Perl में वही चीज़ ज़्यादा तेज़ी और संक्षेप में हो जाती है, इसलिए मैं Perl पसंद करता हूँ। Python कई बार असली काम से ज़्यादा programming के लिए programming जैसा लगता है
मैं काफ़ी ऐसे projects भी बनाता हूँ जिनमें कोई dependency नहीं होती। standard library और single file से भी बहुत कुछ किया जा सकता है। अगर Python installed है तो
curlसे सीधे download करके चला सकते हैं। उदाहरण के लिए, मेरे पास लगभग 2000-line का एक money management CLI tool है, plutus, जो लगभग 12 standard modules ही इस्तेमाल करता है। उसके code का करीब 25% हिस्साargparseसे command parsing में जाता है। मुझे हर parameter के लिए एक line रखकर चीज़ों को साफ़-साफ़ लिखना पसंद हैआपने कहा कि Perl, Python से तेज़ और ज़्यादा ताकतवर है — मैं जानना चाहूँगा कि इसके कुछ ठोस examples क्या हैं
Python में nested data structures के साथ बिना ज़्यादा सोचे सीधे काम करना आसान है। list के अंदर tuple, dictionary वगैरह को खुलकर मिला सकते हैं और एक जैसी syntax से access कर सकते हैं। Perl निस्संदेह ज़्यादा smart और मज़ेदार है, लेकिन शायद इसी वजह से वह दिमाग़ को ज़्यादा उलझा देता है, इसलिए मेरे लिए उतना नहीं है। Python थोड़ा नीरस है, लेकिन उसकी clarity इतनी है कि 5 साल बाद भी code समझा जा सकता है
मुझे लगता है Python standard library से भी काफ़ी काम का है
मैं monorepo structure का समर्थक हूँ, लेकिन एक पुरानी company में इसी approach की वजह से इतना बड़ा और फूला हुआ ढाँचा बन गया था कि कोई भी दूसरे team का code छूने से डरता था। असली समस्या repo नहीं, बल्कि
requirements.txtको पूरे repo के लिए एक ही रखना या build scripts का उलझ जाना था। सिद्धांततः dependency एक बार update करने पर सारा code नए patches के साथ सुरक्षित हो जाना चाहिए था, लेकिन व्यवहार में कोई उसे छू ही नहीं सका। monorepo तभी अच्छी तरह चलता है जब organization बहुत NIH-प्रवृत्ति वाला हो, जैसे Google की तरह सब कुछ खुद बनाना। ऐसे अनुभव के बाद, मैंने उल्टा microservices structure को ज़्यादा महत्व देना शुरू किया, जहाँ हर service organization की team structure से मेल खाती है। Conway's law भी देख सकते हैंPython वह language है जो मेरे लिखे pseudocode के सबसे करीब चलती है। दिमाग़ में जो हिस्से मैं स्पष्ट मानकर छोड़ देता हूँ, Python अक्सर उन्हीं जगहों पर intuitive abstractions दे देता है। मेरा background mathematics-आधारित रहा है, इसलिए यह मुझे बहुत संतोषजनक लगा। अब मुझे दूसरी languages भी पसंद हैं, लेकिन इसमें अभी भी आकर्षण है
मैं लगभग बिल्कुल एक जैसे pattern से projects का ढाँचा बनाता हूँ। यह इतना मिलता-जुलता है कि डरावना लगता है। मुझे लगता है Python developer ecosystem धीरे-धीरे एक जैसे style पर converge कर रहा है। पहले मुझे लगता था कि मेरी पसंदें अनोखी हैं, लेकिन अगर सब यही कर रहे हैं, तो फिर मेरी free will कहाँ गई? यह कुछ वैसा है जैसे common baby names का मामला — आपको लगता है आपने बहुत unique choice की, लेकिन वह असल में popularity में #2 निकलती है
Python में इस तरह की structure 10 साल पहले से लोकप्रिय रही है। आख़िर कई समझदार engineers सोच-विचार के बाद स्वाभाविक रूप से इसी pattern तक पहुँचते लगते हैं
ऐसा लगता है जैसे इंसानी ego किसी pilot-wave quantum wave की तरह पूरे spectrum में फैली हुई हो, और वहीं से वह being में बदलती हो। becoming-being — हँसी आ जाती है
यह देखकर अच्छा लगा कि किसी और को भी Python पसंद आने लगी। मैं मूल रूप से Ruby को तरजीह देता था, लेकिन clients की माँग की वजह से मजबूरी में Python इस्तेमाल करना पड़ा। पहले Ruby काफ़ी slow थी, लेकिन Python को मजबूरी में सीखते-सीखते मैं उससे familiar हो गया, और अब उसे कुछ हद तक enjoy भी करता हूँ। Make के इस्तेमाल पर मेरी थोड़ी अलग राय है; अगर dependencies बिलकुल नहीं हैं, तो यह case statement वाले script से बहुत अलग नहीं है... आधा मज़ाक में कह रहा हूँ, लेकिन आजकल की पीढ़ी Make से परिचित नहीं दिखती, यह थोड़ा खलता है। वही “हमारे ज़माने में…” वाली भावना है
Ruby की syntax कहीं ज़्यादा सुंदर है। सिर्फ़ indentation से scope अलग करना मेरी style नहीं है
मैंने भी शुरुआत case statement वाले script से की थी, और आख़िर में वह एक flat Makefile में बदल गया। Makefile ज़्यादा standard है और random script की तुलना में समझना आसान है
मैं जानना चाहता हूँ कि
DataclassऔरPydantic Basemodelमें से क्या इस्तेमाल करना चाहिए। अगर पहले सेPydanticइस्तेमाल कर रहे हैं, तो क्या सब कुछ उसी में unify कर देना ठीक नहीं होगा? सोचता हूँ कि फिरDataclassइस्तेमाल करने की ज़रूरत क्या हैattrsproject में इस पर बहुत अच्छी तुलना लिखी गई है। attrs official comparison है, जिसमें कुछ bias ज़रूर हो सकता है, लेकिन तर्क काफ़ी मज़बूत हैं। और यह blog भी मददगार हैDataclassnested object validation support नहीं करता। इसलिए functions को arguments pass करने के लिए simple flat structures में dataclass बेहतर है। बहुत सारे arguments को list में लेने से यह ज़्यादा स्पष्ट रहता हैobject creation के समय data validation की वजह से performance hit हो सकती है।
msgspecजैसे कहीं हल्के और तेज़ alternatives भी हैंअगर validation या serialization की ज़रूरत ही नहीं है, तो
Pydanticबेकार का overhead है। मेरा rule यह है: serialization चाहिए तोPydantic, नहीं तोdataclassTypeAdapter(MyDataclass)की तरह existing dataclass को सीधे इस्तेमाल किया जा सकता है, तो अलग से Pydantic model बनाने की ज़रूरत क्यों होहाल में तो मैं Python की बजाय दूसरी language पर चला गया हूँ और उससे ज़्यादा संतुष्ट हूँ। Python के बारे में मेरे विचार इस लेख में हैं। अगर आगे फिर Python इस्तेमाल करने का मौका मिला, तो
uv,ruff,tyजैसी चीज़ें ज़रूर आज़माऊँगाasyncथा। Python मेंasyncioहै, मगर कई competing approaches साथ-साथ हैं, इसलिए कोई ठोस standard नहीं बन पाया। JS में सब कुछ एक ही तरीके पर केंद्रित है, इसलिए वह बहुत आसान लगा। छोटी-छोटी चीज़ें भी जोड़ें तो बड़ा फ़र्क बनता है, और Python में indentation-based scoping, imports में relative path की दिक्कत, JS object syntax जैसी बातों की तुलना में JS ज़्यादा आरामदेह लगा। संबंधित विवरण देखें