Skip to content
This page has been auto-translated and may contain errors.View in English

मॉड्यूल और मानक पुस्तकालय

docs.scrimba.com

Python के पास उपयोग के लिए तैयार उपकरणों का एक विशाल संग्रह है: यादृच्छिकता, गणित, तारीखें, फ़ाइल पथ, और बहुत कुछ। ये उपकरण मॉड्यूल में रहते हैं, और आप उन्हें import के साथ अपने कोड में लाते हैं। आपने पहले से ही Files and exceptions अध्याय में import json का उपयोग किया है। यह अध्याय आयात को पूरी तरह से कवर करता है और मानक पुस्तकालय के सबसे उपयोगी भागों का परिचय देता है।

Python की मानक पुस्तकालय सामान्य समस्याओं के लिए परीक्षित, प्रलेखित समाधान प्रदान करती है। मॉड्यूल कोड संगठन की इकाई हैं: प्रत्येक फ़ाइल एक मॉड्यूल है, __init__.py वाली प्रत्येक निर्देशिका एक पैकेज है। import सिस्टम मॉड्यूल को खोजता है, यदि आवश्यक हो तो उन्हें संकलित करता है, और उन्हें sys.modules में कैश करता है ताकि वे केवल एक बार लोड हों।

एक import वास्तविक कार्य करता है: Python मॉड्यूल को ढूंढता है, इसे एक बार चलाता है, फिर परिणाम को sys.modules (प्रत्येक पहले से लोड किए गए मॉड्यूल का शब्दकोश) में कैश करता है ताकि समान नाम का दूसरा import एक तेज़ लुकअप हो, फिर से चलाना नहीं। import requests मॉड्यूल ऑब्जेक्ट को आपके वर्तमान namespace (कोड के उस बिंदु पर दृश्यमान नामों की तालिका) में नाम requests से जोड़ता है। from requests import get समान लोड चलाता है लेकिन केवल get को जोड़ता है। वास्तविक परियोजनाओं में जो भुगतान करता है वह है जहां Python खोजता है (sys.path), निर्देशिकाएं कैसे आयात योग्य पैकेज बनती हैं (__init__.py), और गोलाकार आयात से कैसे बचें, ये सभी नीचे शामिल हैं।

मॉड्यूल आयात करना

सबसे सरल आयात एक पूरे मॉड्यूल को लाता है और आपको डॉट नोटेशन के साथ इसकी सामग्री का उपयोग करने देता है। आप मॉड्यूल से विशिष्ट नाम भी आयात कर सकते हैं ताकि उनका उपयोग सीधे उपसर्ग के बिना किया जा सके। अलियास लंबे नामों को छोटा करते हैं।

import module मॉड्यूल ऑब्जेक्ट को वर्तमान स्कोप में नाम module से जोड़ता है। from module import name केवल name को जोड़ता है। अलियास (import module as alias) तीसरे पक्ष की पुस्तकालयों के साथ सामान्य हैं। from module import * से बचें: यह namespace को प्रदूषित करता है और यह स्पष्ट नहीं करता कि नाम कहां से आए हैं।

from module import name किसी काम को छोड़ता नहीं है: Python अभी भी पूरे मॉड्यूल को लोड और चलाता है, फिर केवल जिस एक नाम के लिए आपने पूछा है उसे जोड़ता है। जानने वाली समस्या गोलाकार आयात है, जहां दो मॉड्यूल एक दूसरे को आयात करने का प्रयास करते हैं जबकि अभी भी लोड हो रहे हैं, इसलिए उनमें से एक को एक आधा-निर्मित मॉड्यूल दिखता है और एक नाम गायब है। सामान्य सुधार हैं अपराधी import को फ़ंक्शन के अंदर स्थानांतरित करना जिसे इसकी आवश्यकता है (ताकि यह दोनों मॉड्यूल के लोड होने के बाद चले) या साझा कोड को एक तीसरे मॉड्यूल में खींचना जो दोनों आयात कर सकते हैं। जब आपको एक मॉड्यूल आयात करने की आवश्यकता होती है जिसका नाम आप केवल रनटाइम पर जानते हैं, importlib.import_module("name") नाम को एक स्ट्रिंग के रूप में लेता है।

python
import math

math.sqrt(16)     # 4.0
math.pi           # 3.141592653589793
math.floor(3.9)   # 3
math.ceil(3.1)    # 4

किसी मॉड्यूल से विशिष्ट नाम आयात करें ताकि आप उन्हें सीधे उपयोग कर सकें:

python
from math import sqrt, pi

sqrt(16)    # 4.0 ("math." उपसर्ग की आवश्यकता नहीं)
pi          # 3.141592653589793

किसी मॉड्यूल या नाम को अलियास दें ताकि इसे छोटा किया जा सके:

python
import math as m

m.sqrt(16)    # 4.0

from math import sqrt as square_root
square_root(25)    # 5.0

अलियास लोकप्रिय तीसरे पक्ष की पुस्तकालयों के साथ सामान्य हैं (import numpy as np, import pandas as pd)। मानक पुस्तकालय मॉड्यूल के लिए, पूरे नाम का उपयोग करना पसंद करें; यह कोड को अधिक पठनीय बनाता है।

Junoमॉड्यूल आयात करनाimport math पूरे मॉड्यूल को लाता है, फिर आप एक डॉट के साथ अंदर पहुंचते हैं: math.sqrt(16)from math import sqrt एक नाम को पकड़ता है ताकि आप उपसर्ग को छोड़ सकें। as कीवर्ड लंबे आयात का नाम बदलता है, लेकिन मानक-पुस्तकालय सामान के लिए पूरा नाम स्पष्ट रूप से पढ़ता है।
Junoमॉड्यूल आयात करनाimport module मॉड्यूल ऑब्जेक्ट को जोड़ता है, from module import name एक नाम को जोड़ता है, import module as alias इसका नाम बदलता है। from module import * को छोड़ें: यह प्रत्येक नाम को आपके स्कोप में डालता है और छिपाता है कि प्रत्येक कहां से आया है।
Junoमॉड्यूल आयात करनाfrom module import name अभी भी पूरे मॉड्यूल को लोड करता है, यह केवल एक नाम को रखता है। जो काटना आप अंत में मारेंगे वह गोलाकार आयात है, जहां दो मॉड्यूल लोड के बीच एक दूसरे को आयात करते हैं: उस `import` को फ़ंक्शन के अंदर स्थानांतरित करें, या साझा कोड को तीसरे मॉड्यूल में विभाजित करें। importlib.import_module() तब होता है जब नाम केवल रनटाइम पर जाना जाता है।

random

random मॉड्यूल यादृच्छिक संख्याएं उत्पन्न करता है और यादृच्छिक विकल्प बनाता है। इसे गेम, सिमुलेशन, यादृच्छिक नमूनाकरण, और कुछ भी उपयोग करें जिसे अप्रत्याशितता की आवश्यकता होती है। एक seed निर्धारित करने से परिणाम दोहराए जा सकते हैं: समान seed हर बार समान अनुक्रम उत्पन्न करता है।

random एक Mersenne Twister pseudo-random संख्या जनरेटर का उपयोग करता है। seed पूरे अनुक्रम को निर्धारित करता है; समान seed हमेशा समान आउटपुट उत्पन्न करता है। .choice() एक आइटम चुनता है, .choices() प्रतिस्थापन के साथ चुनता है, .sample() बिना प्रतिस्थापन के चुनता है। .shuffle() सूची को जगह पर संशोधित करता है और None लौटाता है।

random pseudo-random संख्याएं उत्पन्न करता है: वे यादृच्छिक दिखते हैं लेकिन एक निश्चित सूत्र से आते हैं जो एक प्रारंभिक मान (seed) द्वारा संचालित होता है, इसलिए समान seed हर मशीन पर समान अनुक्रम देता है, जो यही है जो एक परीक्षण को दोहराए जाने योग्य बनाता है। उत्पादन में जो नियम मायने रखता है: random को कभी भी किसी ऐसी चीज़ के लिए उपयोग न करें जिसे कोई व्यक्ति शोषण कर सके, जैसे पासवर्ड, सत्र टोकन, या पासवर्ड-रीसेट कोड। यह डिज़ाइन द्वारा पूर्वानुमानित है, इसलिए एक हमलावर जो पर्याप्त आउटपुट देखता है वह बाकी को अनुमान लगा सकता है। उनके लिए, secrets मॉड्यूल के लिए पहुंचें, जो ऑपरेटिंग सिस्टम की सुरक्षित यादृच्छिकता से निकालता है। random.SystemRandom() आपको परिचित random विधि नाम के पीछे उसी सुरक्षित स्रोत को देता है यदि आप API को स्विच नहीं करना चाहते हैं।

python
import random

random.random()              # 0 और 1 के बीच float (एक्सक्लूसिव)
random.randint(1, 10)        # 1 से 10 तक पूर्णांक (दोनों समावेशी)
random.uniform(1.0, 10.0)    # 1.0 और 10.0 के बीच float

colours = ["लाल", "हरा", "नीला"]
random.choice(colours)       # एक आइटम चुनता है
random.choices(colours, k=3) # k आइटम चुनता है (प्रतिस्थापन के साथ)
random.sample(colours, k=2)  # k आइटम चुनता है (प्रतिस्थापन के बिना)

numbers = [1, 2, 3, 4, 5]
random.shuffle(numbers)      # जगह पर शफल करता है, None लौटाता है

दोहराए जाने योग्य परिणामों के लिए (परीक्षण और डेटा विज्ञान में उपयोगी), उत्पन्न करने से पहले एक seed निर्धारित करें:

python
random.seed(42)
random.randint(1, 100)   # seed 42 के लिए हमेशा समान मान

समान seed हर बार, किसी भी मशीन पर समान अनुक्रम उत्पन्न करता है।

Junorandomrandom.choice() किसी सूची से एक आइटम चुनता है, random.randint(1, 10) एक श्रृंखला में एक पूर्ण संख्या देता है, अंत समावेशी। क्या आप हर चलाने के लिए समान परिणाम चाहते हैं, मान लें कि एक परीक्षण के लिए? पहले random.seed() को कॉल करें और अनुक्रम लॉक हो जाता है।
Junorandom.choice() एक चुनता है, .choices() प्रतिस्थापन के साथ चुनता है, .sample() बिना। .shuffle() सूची को जगह पर पुनः क्रम देता है और None लौटाता है, इसलिए कभी भी nums = random.shuffle(nums) न लिखें। seed पूरे अनुक्रम को ठीक करता है, जो यही है कि आप एक यादृच्छिक परीक्षण को दोहराया जा सकता है कैसे बनाते हैं।
Junorandomrandom pseudo-random है और डिज़ाइन द्वारा पूर्वानुमानित है, इसलिए यह गेम और परीक्षणों के लिए ठीक है लेकिन कुछ भी गलत है जो एक हमलावर शोषण कर सकता है। टोकन, पासवर्ड, और रीसेट कोड के लिए secrets का उपयोग करें। दोहराए जाने योग्य मामलों के लिए random.seed() रखें जहां आप वास्तव में अनुक्रम को दोहराना चाहते हैं।

math

math मॉड्यूल Numbers अध्याय में मिलने वाले बुनियादी अंकगणित ऑपरेटरों से परे अधिक उन्नत गणितीय संचालन जोड़ता है। वर्गमूल, शक्तियां, लॉगरिदम, त्रिकोणमिति, और विशेष मान जैसे pi और अनंत सभी यहां हैं।

math मानक गणितीय फ़ंक्शन के C-स्तर के कार्यान्वयन प्रदान करता है। ध्यान दें कि math.pow() हमेशा एक float लौटाता है, जबकि Python का ** ऑपरेटर पूर्णांक आधार और घातांक के लिए int लौटाता है। math.log(x, base) किसी भी आधार पर लॉगरिदम की गणना करता है; math.log(x) प्राकृतिक लॉगरिदम की गणना करता है।

विवरण जो वास्तविक कोड में काटता है वह है nan (जिसका अर्थ है "एक संख्या नहीं", float जो आप अनिर्धारित परिणामों जैसे 0/0 या एक विफल पार्स से प्राप्त करते हैं) और inf (अनंत)। एक nan कभी भी कुछ भी नहीं के बराबर है, यहां तक कि स्वयं, इसलिए x == float("nan") हमेशा False है। इसका मतलब है कि आप इसे == के साथ परीक्षण नहीं कर सकते; math.isnan(x) का उपयोग करें, और अनंत के लिए math.isinf(x)। अन्य आदत रखने लायक: दो फ़्लोट की तुलना करते समय a == b पर math.isclose(a, b) को प्राथमिकता दें, क्योंकि फ्लोटिंग-पॉइंट राउंडिंग सटीक समानता को अविश्वसनीय बनाती है। पूरे सरणियों की संख्याओं पर गणित के लिए एक समय में एक की बजाय, numpy मानक उपकरण है, हालांकि यह इस गाइड के बाहर है।

python
import math

math.sqrt(25)        # 5.0
math.pow(2, 10)      # 1024.0 (2 ** 10 के समान लेकिन हमेशा float लौटाता है)
math.log(100, 10)    # 2.0 (log आधार 10)
math.log(math.e)     # 1.0 (प्राकृतिक लॉग)

math.sin(math.pi / 2)   # 1.0
math.cos(0)             # 1.0

math.ceil(3.2)    # 4
math.floor(3.9)   # 3
math.trunc(3.9)   # 3 (सकारात्मकों के लिए int() के समान)

math.inf          # अनंत
math.isnan(float("nan"))   # True
math.isinf(math.inf)       # True
Junomathmath `+ - * /` के बाद सब कुछ को कवर करता है: वर्गमूल, शक्तियां, लॉग, त्रिकोणमिति, साथ ही `math.pi` जैसे स्थिरांक। इसके लिए पहुंचें जैसे ही गणना को बुनियादी ऑपरेटरों से अधिक की आवश्यकता होती है, और आप सूत्र को स्वयं लिखना छोड़ देते हैं।
Junomathmath में वर्गमूल, लॉग, और त्रिकोणमिति हैं। एक चीज़ ध्यान देने योग्य है: math.pow(2, 10) हमेशा एक float लौटाता है, जबकि 2 ** 10 पूर्णांक इनपुट के लिए एक int रहता है। math.log(x, base) कोई भी आधार लेता है, math.log(x) प्राकृतिक लॉग है।
Junomath जाल `nan` और `inf` हैं: `nan` कभी स्वयं के बराबर नहीं है, इसलिए `==` के साथ नहीं, `math.isnan()` के साथ परीक्षण करें। और फ़्लोट की तुलना `==` के बजाय `math.isclose()` के साथ करें, क्योंकि राउंडिंग सटीक समानता को अविश्वसनीय बनाती है। पूरे सरणियों की संख्याओं के लिए, वह `numpy` क्षेत्र है।

datetime

datetime मॉड्यूल तारीखों और समय को संभालता है। datetime.now() आपको वर्तमान तारीख और समय देता है। strftime() इसे एक स्ट्रिंग के रूप में प्रारूपित करता है। strptime() एक स्ट्रिंग को datetime में पार्स करता है। timedelta एक अवधि का प्रतिनिधित्व करता है जिसे आप जोड़ या घटा सकते हैं।

datetime, date, और timedelta मुख्य वर्ग हैं। strftime() प्रारूप कोड का उपयोग करके datetime को एक स्ट्रिंग के रूप में प्रारूपित करता है। strptime() एक प्रारूप पैटर्न दिए गए एक स्ट्रिंग को पार्स करता है। timedelta अंकगणित का समर्थन करता है: आप तारीखों में अवधि जोड़ या घटा सकते हैं और <, >, - के साथ datetimes की तुलना कर सकते हैं।

उत्पादन में समस्या यह है कि एक सादा datetime.now() naive है: इसमें कोई timezone नहीं है, इसलिए यह वास्तव में नहीं जानता कि यह दुनिया के किस हिस्से का प्रतिनिधित्व करता है। दो naive datetimes विभिन्न मशीनों से तुलनीय दिखते हैं लेकिन चुपचाप नहीं हैं, और यह अस्पष्टता घंटे-से-काटने में बग का कारण बनती है। समाधान aware datetimes (जो timezone ले जाते हैं) में काम करना है, और सिस्टम के बीच संग्रहीत या भेजी गई किसी भी चीज़ के लिए UTC पर मानकीकृत करना है: datetime.now(timezone.utc)। केवल किनारे पर स्थानीय समय में परिवर्तित करें, जब आप इसे किसी व्यक्ति को दिखाते हैं। zoneinfo मॉड्यूल का उपयोग नामित zones जैसे "Europe/Oslo" के लिए करें, जो दिन के प्रकाश बचत पारियों को आपके लिए संभालता है। एक और नियम: datetime.now() अंतर के साथ कभी भी बीते हुए समय को मापें, क्योंकि सिस्टम घड़ी कूद सकती है (एक sync या एक मैनुअल परिवर्तन); अवधि के लिए time.perf_counter(), एक काउंटर जो केवल आगे बढ़ता है, का उपयोग करें।

python
from datetime import datetime, date, timedelta

now = datetime.now()             # वर्तमान तारीख और समय
today = date.today()             # केवल वर्तमान तारीख

print(now.year, now.month, now.day)
print(now.hour, now.minute, now.second)

# प्रारूपण
print(now.strftime("%Y-%m-%d"))           # "2024-01-15"
print(now.strftime("%d %B %Y, %H:%M"))   # "15 जनवरी 2024, 09:42"

# पार्सिंग
deadline = datetime.strptime("2024-12-31", "%Y-%m-%d")

# अंकगणित
tomorrow = today + timedelta(days=1)
next_week = today + timedelta(weeks=1)
diff = deadline - now
print(f"{diff.days} दिन deadline तक")

सामान्य strftime कोड:

कोडअर्थउदाहरण
%Y4-अंकीय वर्ष2024
%mमहीना (zero-padded)01
%dदिन (zero-padded)15
%Hघंटा (24h)09
%Mमिनट42
%Bपूरा महीने का नामजनवरी
Junodatetimedatetime.now() आपको वर्तमान तारीख और समय देता है। strftime() इसे %Y-%m-%d जैसे कोड के साथ एक स्ट्रिंग में बदल देता है, और strptime() दूसरे तरीके से जाता है, एक स्ट्रिंग को वापस पार्स करता है। timedelta एक अवधि है जिसे आप जोड़ या घटा सकते हैं, इसलिए today + timedelta(days=1) कल है।
Junodatetimedatetime, date, और timedelta मुख्य हैं। strftime() कोड के साथ प्रारूपित करता है, strptime() एक मेल पैटर्न के साथ पार्स करता है। तारीखें अंकगणित करती हैं: दो को घटाएं और आपको एक `timedelta` मिलता है, आगे या पीछे स्थानांतरित करने के लिए एक `timedelta` जोड़ें।
Junodatetime एक सादा datetime.now() naive है, कोई timezone नहीं, जो चुपचाप टूट जाता है एक बार दो मशीन शामिल हों। datetime.now(timezone.utc) के साथ UTC में संग्रहीत और पास करें, केवल प्रदर्शन के लिए स्थानीय में परिवर्तित करें, और नामित zones के लिए `zoneinfo` पर निर्भर करें। और बीते हुए समय को now() अंतर के साथ कभी न मापें, `time.perf_counter()` का उपयोग करें, क्योंकि दीवार की घड़ी कूद सकती है।

os और pathlib

pathlib फ़ाइल पथों के साथ काम करने का आधुनिक तरीका है। Path ऑब्जेक्ट आपको / ऑपरेटर का उपयोग करके पथों को बनाने, निरीक्षण करने और नेविगेट करने देते हैं। os पर्यावरण चर और निम्न-स्तरीय OS संचालन तक पहुंच देता है। नए कोड के लिए pathlib को प्राथमिकता दें।

pathlib.Path क्वेरी और नेविगेशन के लिए विधियों के साथ वस्तुओं के रूप में फ़ाइलसिस्टम पथों का प्रतिनिधित्व करता है। / ऑपरेटर पथ घटकों को साफ-सुथरे तरीके से जोड़ता है, OS-विशिष्ट विभाजकों को स्वचालित रूप से संभालता है। os.environ पर्यावरण चर के लिए एक dict-जैसी वस्तु है; os.environ.get("KEY", "default") गायब चर के लिए सुरक्षित है।

Path ऑपरेटिंग सिस्टम को स्वचालित रूप से अनुकूल करता है, इसलिए समान कोड हर मशीन पर सही विभाजक के साथ पथों को जोड़ता है: Path("data") / "file.csv" लिखें, कभी भी हाथ से निर्मित "data/" + name स्ट्रिंग न लिखें जो Windows पर टूट जाते हैं। दो व्यावहारिक नोट्स। सबसे पहले, .glob(), .rglob(), और .iterdir() generators लौटाते हैं (वे एक बार में एक प्रविष्टि प्रदान करते हैं पूर्ण सूची बनाने की बजाय), इसलिए उन्हें list() में लपेटें यदि आपको दो बार लूप करने या आगे की गणना जानने की आवश्यकता है; एक विशाल निर्देशिका के लिए, आलसी रूप से पुनरावृत्ति बिंदु है। दूसरा, कुछ पुरानी पुस्तकालयें अभी भी एक सादा स्ट्रिंग की अपेक्षा करती हैं Path ऑब्जेक्ट के बजाय; जब कोई एक Path को अस्वीकार करता है, तो str(path) को पास करें और आगे बढ़ें। एक पर्यावरण चर पढ़ने के लिए, हमेशा os.environ.get("KEY", "default") का उपयोग करें os.environ["KEY"] के बजाय, क्योंकि अनुक्रमित फॉर्म KeyError उठाता है जब चर अनसेट हो, जो ताज़ी तैनाती में सामान्य मामला है।

python
from pathlib import Path

p = Path("data/reports")

p.exists()           # True यदि पथ मौजूद है
p.is_dir()           # True यदि यह एक निर्देशिका है
p.is_file()          # True यदि यह एक फ़ाइल है

p.mkdir(parents=True, exist_ok=True)   # निर्देशिकाएं बनाएं

for f in p.glob("*.csv"):              # निर्देशिका में सभी CSV फ़ाइलें
    print(f.name)                      # फ़ाइलनाम

report = p / "report_jan.csv"          # / ऑपरेटर पथों को जोड़ता है
report.stem       # "report_jan" (विस्तार के बिना नाम)
report.suffix     # ".csv"
report.parent     # Path("data/reports")

content = report.read_text()           # सीधे फ़ाइल सामग्री पढ़ें
report.write_text("नई सामग्री\n")    # सीधे लिखें

os मॉड्यूल के लिए:

python
import os

os.getcwd()                        # वर्तमान कार्यशील निर्देशिका
os.listdir(".")                    # निर्देशिका सामग्री सूचीबद्ध करें
os.path.exists("data.txt")        # True यदि पथ मौजूद है
os.path.join("data", "file.txt")  # "data/file.txt" (क्रॉस-प्लेटफॉर्म)
os.environ.get("HOME")            # एक पर्यावरण चर पढ़ें

नए कोड के लिए pathlib को प्राथमिकता दें। os का उपयोग करें जब आपको पर्यावरण चर की आवश्यकता हो या पुरानी APIs के साथ काम कर रहे हों जो स्ट्रिंग की अपेक्षा करते हैं।

Junoos और pathlibpathlib.Path एक फ़ाइल पथ को एक वस्तु के रूप में मानता है जिसे आप पॉक कर सकते हैं: .exists(), .read_text(), .write_text(), .glob()। `/` ऑपरेटर टुकड़ों को जोड़ता है, इसलिए p / "report.csv" एक वास्तविक पथ की तरह पढ़ता है। नए कोड में पुराने os.path पर `pathlib` के लिए पहुंचें।
Junoos और pathlibPath `/` के साथ जोड़ता है और आपके लिए OS विभाजक को संभालता है, इसलिए पथ पोर्टेबल रहते हैं। os.environ पर्यावरण चर के लिए dict-जैसा है, और os.environ.get("KEY", "default") सुरक्षित पढ़ है, यह एक गायब कुंजी पर खिड़की नहीं खोलेगा।
Junoos और pathlib `Path` और `/` के साथ पथ बनाएं, कभी भी गोंद स्ट्रिंग न बनाएं जो Windows पर टूट जाते हैं। .glob() और दोस्त जनरेटर सौंपते हैं, इसलिए उन्हें list() करें यदि आपको दो बार लूप करने की आवश्यकता है। और env vars को os.environ.get(key, default) के साथ पढ़ें: ब्रैकेट फॉर्म `KeyError` उठाता है जैसे ही एक चर अनसेट हो, जो ठीक ताज़ा-तैनाती मामला है।

timeit

timeit मापता है कि कोड कितने समय तक चलता है। यह उपयोगी है जब आप दो दृष्टिकोणों की तुलना करना चाहते हैं और तेजी से चुनना चाहते हैं। एक स्थिर माप पाने के लिए कोड को कई बार चलाएं।

timeit.timeit(stmt, setup, number) stmt को number बार चलाकर और कुल बीता हुआ समय सेकंड में लौटाकर समय देता है। setup स्ट्रिंग समयबद्ध लूप से पहले एक बार चलती है। प्रति-कॉल समय प्राप्त करने के लिए परिणाम को number से विभाजित करें। अधिक पुनरावृत्तियां सिस्टम शेड्यूलिंग से शोर को कम करती हैं।

timeit एक microbenchmark के लिए सही उपकरण है: अलगाव में एक छोटे स्निपेट का समय, कई बार चलाएं ताकि शेड्यूलिंग शोर औसत हो। यह आपके लिए उस शोर को शांत करता है, लेकिन एक एकल चलाना अभी भी अविश्वसनीय है, इसलिए एक संख्या के बजाय कई दोहराव में से सर्वश्रेष्ठ लें। बचने के लिए गलती एक पूरे प्रोग्राम में एक धीमापन खोजने के लिए इसका उपयोग करना है: यह केवल आपके द्वारा सौंपे गए स्निपेट का समय देता है, इसलिए यह नहीं बता सकता कि कौन सा फ़ंक्शन वास्तव में धीमा है। इसके लिए, cProfile का उपयोग करें, जो आपके वास्तविक प्रोग्राम को चलाता है और रिपोर्ट करता है कि समय कहां गया। अंगूठा का नियम: timeit दो कार्यान्वयन की तुलना करने के लिए, पहली जगह में बाधा को खोजने के लिए cProfile

python
import timeit

# एक एकल कथन को समय दें
timeit.timeit("sum(range(1000))", number=10000)

# एक अधिक जटिल ब्लॉक को समय दें
setup = "data = list(range(1000))"
code = "[x * 2 for x in data]"
time = timeit.timeit(code, setup=setup, number=10000)
print(f"10,000 चलाने के लिए {time:.4f} सेकंड")

number कितनी बार दोहराएं है। अधिक पुनरावृत्तियां अधिक स्थिर माप देती हैं।

Junotimeittimeit.timeit() कोड के एक टुकड़े को बार-बार चलाकर समय देता है, फिर आप एक स्थिर प्रति-कॉल संख्या के लिए चलाने की गणना से विभाजित करते हैं। यह है कि आप "इनमें से कौन सा दो तेजी से है" को अनुमान लगाने की बजाय कैसे तय करते हैं। एक चलाना बहुत शोरपूर्ण है विश्वास करने के लिए, तो इसे लूप करने दें।
Junotimeittimeit.timeit(stmt, setup, number) `stmt` को कि कई बार चलाता है और कुल सेकंड लौटाता है; `setup` स्ट्रिंग लूप से पहले एक बार चलती है। प्रति-कॉल समय के लिए `number` से विभाजित करें, और शेड्यूलिंग शोर को डुबोने के लिए दोहराव को बढ़ाएं।
Junotimeit `timeit` microbenchmarks के लिए है: दो छोटे स्निपेट की तुलना करना, एक एकल शोरपूर्ण चलाने के बजाय सर्वश्रेष्ठ-of-कई। यह नहीं बता सकता कि एक वास्तविक प्रोग्राम में कौन सा फ़ंक्शन धीमा है, क्योंकि यह केवल जो आप फीड करते हैं उसका समय देता है। बाधा को खोजने के लिए `cProfile` का उपयोग करें, फिर ठीक करने की तुलना करने के लिए `timeit`।

string

string मॉड्यूल अक्षरों, अंकों और विराम चिह्न के लिए पूर्व-निर्मित स्ट्रिंग स्थिरांक प्रदान करता है। उपयोगी जब आपको वर्णों को जांचने या एक विशिष्ट वर्णमाला से यादृच्छिक स्ट्रिंग बनाने की आवश्यकता होती है।

string मॉड्यूल स्थिरांक (ascii_letters, digits, punctuation) सादे स्ट्रिंग हैं जिन्हें आप अनुक्रमित कर सकते हैं, पुनरावृत्ति कर सकते हैं, या in के साथ उपयोग कर सकते हैं। random.choices() के साथ उन्हें संयोजित करना यादृच्छिक टोकन या पासवर्ड उत्पन्न करने का मानक तरीका है।

ये स्थिरांक साधारण स्ट्रिंग हैं, इसलिए char in string.ascii_letters जांच हर बार पूरी स्ट्रिंग को स्कैन करती है। वह स्कैन O(n) है: काम स्ट्रिंग की लंबाई के साथ बढ़ता है, एक बार ठीक है, एक टाइट लूप में बर्बाद है। यदि आप सदस्यता को बार-बार परीक्षण कर रहे हैं, तो एक बार set बनाएं (letters = set(string.ascii_letters)) और इसके विरुद्ध जांच करें, क्योंकि एक सेट लुकअप कितने प्रविष्टियां रखता है इससे कोई फर्क नहीं पड़ता तेजी से रहता है। यहां अन्य उपयोगी टुकड़ा string.Template है, जो सादा $name प्रतिस्थापन करता है: जब एक टेम्पलेट उपयोगकर्ता इनपुट या एक कॉन्फ़िग फ़ाइल से आता है, तो यह एक f-string या str.format() को अविश्वसनीय पाठ सौंपने से अधिक सुरक्षित है, क्योंकि यह आपके चर या कॉल विधियों तक नहीं पहुंच सकता।

python
import string

string.ascii_lowercase   # "abcdefghijklmnopqrstuvwxyz"
string.ascii_uppercase   # "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
string.ascii_letters     # दोनों संयुक्त
string.digits            # "0123456789"
string.punctuation       # सभी विराम चिह्न वर्ण

जब आपको वर्णों को जांचने या यादृच्छिक स्ट्रिंग बनाने की आवश्यकता हो तो उपयोगी:

python
import string, random

chars = string.ascii_letters + string.digits
password = "".join(random.choices(chars, k=12))
Junostring `string` मॉड्यूल आपको तैयार-निर्मित वर्ण सेट देता है: string.ascii_letters, string.digits, string.punctuation। वे सादे स्ट्रिंग हैं, इसलिए आप उन्हें लूप कर सकते हैं या उनसे नमूना ले सकते हैं। जब भी आपको एक ज्ञात वर्णमाला की आवश्यकता हो, तब के लिए उपयोगी।
Junostringstring.ascii_letters, string.digits और दोस्त सादे स्ट्रिंग हैं जिन्हें आप अनुक्रमित कर सकते हैं, पुनरावृत्ति कर सकते हैं, या `in` के साथ परीक्षण कर सकते हैं। उन्हें random.choices() के साथ जोड़ी और आपके पास एक यादृच्छिक टोकन या पासवर्ड के लिए मानक नुस्खा है। ध्यान दें कि random वास्तविक रहस्य के लिए सुरक्षित नहीं है।
Junostring स्थिरांक सादे स्ट्रिंग हैं, इसलिए char in string.ascii_letters हर कॉल पर पूरी चीज़ को स्कैन करता है: यदि आप एक लूप में जांच रहे हैं तो एक बार `set` बनाएं। और जब एक टेम्पलेट उपयोगकर्ता इनपुट से आता है, तो string.Template के साथ $name एक f-string से अधिक सुरक्षित है, क्योंकि यह आपके चर तक नहीं पहुंच सकता।

अपने स्वयं के मॉड्यूल बनाना

कोई भी Python फ़ाइल एक मॉड्यूल है। इसे किसी अन्य फ़ाइल से उपयोग करने के लिए, फ़ाइलनाम (.py के बिना) द्वारा इसे आयात करें। आप पूरे मॉड्यूल को आयात कर सकते हैं और डॉट नोटेशन के साथ इसकी सामग्री का उपयोग कर सकते हैं, या विशिष्ट नाम सीधे आयात कर सकते हैं।

जब Python एक मॉड्यूल आयात करता है, तो वह फ़ाइल को ऊपर से नीचे तक एक बार निष्पादित करता है और परिणाम को sys.modules में कैश करता है। समान मॉड्यूल के बाद के आयात फ़ाइल को फिर से चलाए बिना कैश किए गए ऑब्जेक्ट को लौटाते हैं। बड़ी परियोजनाओं के लिए, मॉड्यूल को packages में संगठित किया जाता है: __init__.py फ़ाइल वाली निर्देशिकाएं।

जब आप import utils लिखते हैं, तो Python sys.path में निर्देशिकाओं को क्रम में खोजता है, आपके द्वारा चलाई गई स्क्रिप्ट की फ़ोल्डर से शुरू करते हुए। यह सबसे सामान्य "मेरी मशीन पर काम करता है" आयात बग का स्रोत है: एक फ़ाइल को एक अलग कार्यशील निर्देशिका से चलाएं और जिस फ़ोल्डर की अपेक्षा करता है वह पथ पर नहीं हो सकता, इसलिए आयात विफल हो जाता है। विश्वसनीय सुधार एक ढीली फ़ाइल की ओर इशारा करने की बजाय एक पैकेज के रूप में परियोजना को चलाना है (python -m mypackage.main)। एक package __init__.py फ़ाइल वाली मॉड्यूल की एक निर्देशिका है (यह खाली हो सकता है; इसकी उपस्थिति यही है जो Python को बताता है कि फ़ोल्डर आयात योग्य है)। एक पैकेज के अंदर, एक relative import जैसे from . import helpers का अर्थ है "इस समान पैकेज से", जो पैकेज का नाम बदला जाने या स्थानांतरित किए जाने पर भी आयात को काम करता रखता है। एक तीव्र किनारा: importlib.reload() एक मॉड्यूल को पुनः चलाता है, लेकिन कोई भी नाम जिसे आपने पहले से आयात किया है पुरानी संस्करण को इंगित करते रहते हैं, इसलिए पुनः लोडिंग REPL में एक त्वरित प्रयोग के अलावा कुछ भी के लिए अविश्वसनीय है।

python
# utils.py
def clamp(value, lo, hi):
    return max(lo, min(value, hi))

PI = 3.14159
python
# main.py
import utils

utils.clamp(150, 0, 100)   # 100
utils.PI                    # 3.14159

from utils import clamp
clamp(50, 0, 100)           # 50

Python आयात करने वाली फ़ाइल के समान निर्देशिका (और कुछ अन्य स्थानों) में देखकर मॉड्यूल को ढूंढता है। बड़ी परियोजनाओं के लिए, मॉड्यूल को packages में संगठित किया जाता है: __init__.py फ़ाइल वाली निर्देशिकाएं।

Junoअपने स्वयं के मॉड्यूल बनाना कोई भी .py फ़ाइल पहले से ही एक मॉड्यूल है: इसे .py के बिना अपने फ़ाइलनाम द्वारा आयात करें, और इसके फ़ंक्शन और चर आपके हैं उपयोग करने के लिए। import utils फिर utils.clamp(...), या एक नाम के साथ from utils import clamp खींचें। यह है कि आप एक बढ़ती हुई प्रोग्राम को फ़ाइलों में कैसे विभाजित करते हैं।
Junoअपने स्वयं के मॉड्यूल बनाना एक मॉड्यूल आयात करना इसे ऊपर से नीचे तक एक बार चलाता है, फिर इसे `sys.modules` में कैश करता है, इसलिए बाद के आयात फ़ाइल को फिर से चलाए बिना समान ऑब्जेक्ट लौटाते हैं। शीर्ष स्तर के कोड को हल्का रखें क्योंकि, कुछ भी भारी आयात समय पर चलता है। संबंधित मॉड्यूल को एक पैकेज में समूहित करें: `__init__.py` वाली एक फ़ोल्डर।
Junoअपने स्वयं के मॉड्यूल बनाना आयात `sys.path` के माध्यम से हल करता है, स्क्रिप्ट की अपनी फ़ोल्डर से शुरू करते हुए, यही कारण है कि गलत निर्देशिका से एक ढीली फ़ाइल चलाना आयात को तोड़ता है। इसके बजाय एक पैकेज के रूप में चलाएं: `python -m pkg.main`। और `importlib.reload()` को तेजी से REPL pokes से परे विश्वास न करें, क्योंकि नाम जिन्हें आपने आयात किया है पुरानी संस्करण को इंगित करते रहते हैं।

__name__ == "__main__"

जब Python किसी फ़ाइल को सीधे चलाता है, तो __name__ को "__main__" पर सेट किया जाता है। जब समान फ़ाइल को एक मॉड्यूल के रूप में आयात किया जाता है, तो __name__ मॉड्यूल नाम होता है। यह पैटर्न आपको ऐसा कोड लिखने देता है जो तब चलता है जब आप फ़ाइल को सीधे निष्पादित करते हैं लेकिन अन्य मॉड्यूल द्वारा फ़ाइल आयात किए जाने पर छोड़ दिया जाता है।

if __name__ == "__main__": निष्पादनीय मॉड्यूल कोड के लिए मानक गार्ड है। यह एक मॉड्यूल को आयात योग्य (इसके फ़ंक्शन को प्रकट करते हुए) और सीधे चलाने योग्य (परीक्षण या डेमो कोड के साथ) दोनों बनाता है। इसके बिना, मॉड्यूल को आयात करना किसी भी शीर्ष-स्तर के कोड को निष्पादित करेगा, जो लगभग कभी भी वांछित नहीं है।

Python __name__ को "__main__" सेट करता है जिस फ़ाइल को आपने वास्तव में चलाया है और मॉड्यूल के अपने नाम पर कुछ भी आयात किया गया है। गार्ड import-time side effects (कोड जो कुछ करता है जब मॉड्यूल लोड होता है, जैसे कि तर्कों को पार्स करना, एक कनेक्शन खोलना, या एक डेमो चलाना) को अन्य फ़ाइल आपको आयात करने के तुरंत बाद नहीं जलाने के लिए मौजूद है। पैटर्न जो पकड़ता है: वास्तविक काम को एक main() फ़ंक्शन में डालें और इसे गार्ड के अंदर कॉल करें, इसलिए आयातकर्ता को फ़ंक्शन मिलते हैं बिना स्टार्टअप के, और फ़ाइल अभी भी अकेले깨끗게चलती है। गार्ड को छोड़ना यह क्लासिक कारण है कि एक परीक्षण सूट रहस्यमय रूप से किसी का डेमो कोड चलाता है जैसे ही यह मॉड्यूल को आयात करता है।

python
# utils.py
def clamp(value, lo, hi):
    return max(lo, min(value, hi))

if __name__ == "__main__":
    # यह केवल तब चलता है जब आप करते हैं: python utils.py
    # नहीं जब आप करते हैं: import utils
    print(clamp(150, 0, 100))   # 100

यह किसी भी मॉड्यूल के लिए मानक पैटर्न है जो स्टैंडअलोन स्क्रिप्ट के रूप में भी उपयोगी है।

Juno__name__ == '__main__'if __name__ == "__main__": एक फ़ाइल को एक आयात योग्य मॉड्यूल और एक चलाने योग्य स्क्रिप्ट दोनों बनाता है। गार्ड के अंतर्गत कोड तब चलता है जब आप python utils.py करते हैं, और तब छोड़ दिया जाता है जब कोई अन्य फ़ाइल import utils करती है। एक मॉड्यूल के नीचे एक त्वरित डेमो या परीक्षण को छिपाने के लिए उपयोगी।
Juno__name__ == '__main__'__name__ केवल आपके द्वारा सीधे चलाई गई फ़ाइल में `"__main__"` है। गार्ड आपके डेमो या परीक्षण कोड को चलाने से रोकता है जब मॉड्यूल को आयात किया जाता है, जो अन्यथा चुपचाप होता है। यह एक फ़ाइल को पुस्तकालय और स्क्रिप्ट दोनों के रूप में काम करने का मानक तरीका है।
Juno__name__ == '__main__' गार्ड import-time साइड इफेक्ट्स को रोकता है, तर्क पार्सिंग, कनेक्शन, डेमो, जब कोई आपको आयात करता है तो नहीं जलते हैं। काम को `main()` में डालें और गार्ड के अंतर्गत इसे कॉल करें: आयातकर्ता को फ़ंक्शन मिलते हैं, फ़ाइल अभी भी अकेले चलती है। इसे छोड़ें और एक परीक्षण सूट को आपके डेमो को चलाते हुए देखें जैसे ही यह मॉड्यूल को आयात करता है।

मानक पुस्तकालय हाइलाइट

जानने लायक कुछ और मॉड्यूल। प्रत्येक एक सामान्य समस्या को हल करता है जिसे स्वयं को लागू करने के लिए महत्वपूर्ण काम करना पड़ता।

मानक पुस्तकालय व्यापक है; नीचे की हाइलाइट्स वे हैं जिन्हें आप उत्पादन कोड में सबसे अधिक सामना करेंगे। एक संपूर्ण संदर्भ के लिए, docs.python.org/3/library आधिकारिक स्रोत है।

मानक पुस्तकालय अच्छी तरह से परीक्षित, प्रलेखित मॉड्यूल का एक सुविचारित सेट है। एक तीसरे पक्ष के पैकेज के लिए पहुंचने से पहले, जांचें कि क्या मानक पुस्तकालय के पास एक समाधान है: functools, itertools, contextlib, dataclasses, typing, और abc प्रत्येक उपकरण प्रदान करते हैं जिन्हें तीसरे पक्ष की पैकेज अक्सर पुनः खोजती हैं।

collections: विशेषीकृत कंटेनर प्रकार:

python
from collections import Counter, defaultdict, deque

Counter(["a", "b", "a", "c", "a"])   # Counter({'a': 3, 'b': 1, 'c': 1})
defaultdict(list)                      # dict जो स्वचालित रूप से लापता कुंजियों को बनाता है
deque([1, 2, 3], maxlen=5)            # दोनों सिरों से तेजी से append/pop

itertools: iterables के साथ काम करने के लिए उपकरण:

python
import itertools

list(itertools.chain([1, 2], [3, 4]))          # [1, 2, 3, 4]
list(itertools.islice(range(100), 5))          # [0, 1, 2, 3, 4]
list(itertools.combinations([1, 2, 3], 2))     # [(1, 2), (1, 3), (2, 3)]
list(itertools.product([0, 1], repeat=2))      # [(0,0), (0,1), (1,0), (1,1)]

sys: Python दुभाषिए तक पहुंच:

python
import sys

sys.argv        # कमांड-लाइन तर्कों की सूची
sys.exit(1)     # एक स्थिति कोड के साथ बाहर निकलें
sys.version     # Python संस्करण string

तीसरे पक्ष की पैकेज: मानक पुस्तकालय से परे, pip सामुदायिक पैकेज स्थापित करता है:

bash
pip install requests    # HTTP पुस्तकालय
pip install pandas      # डेटा हेरफेर
pip install numpy       # संख्यात्मक कंप्यूटिंग

तीसरे पक्ष की पैकेज इस गाइड के दायरे से बाहर हैं, लेकिन पैटर्न हमेशा समान है: pip install, फिर import

व्यावहारिक रूप में

समय के साथ अद्वितीय गेम आईडी बनाने के लिए random, string, और datetime को संयोजित करना:

python
import random
import string
from datetime import datetime

def generate_game_id(length: int = 8) -> str:
    chars = string.ascii_uppercase + string.digits
    return "".join(random.choices(chars, k=length))

def timestamp() -> str:
    return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

game_id = generate_game_id()
print(f"[{timestamp()}] गेम {game_id} शुरू किया जा रहा है")

scores = [random.randint(50, 100) for _ in range(5)]
print(f"राउंड स्कोर: {scores}")
print(f"सर्वश्रेष्ठ: {max(scores)}")

एक निर्देशिका में फ़ाइलें खोजने और उनके आकार की रिपोर्ट करने के लिए pathlib और datetime का उपयोग करना:

python
from pathlib import Path
from datetime import datetime

def find_files(directory: str, pattern: str = "*.csv") -> list[Path]:
    return sorted(Path(directory).glob(pattern))

def timestamp() -> str:
    return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

files = find_files(".", "*.md")[:3]
print(f"[{timestamp()}] {len(files)} फ़ाइल(एं) मिली")
for f in files:
    size = f.stat().st_size if f.exists() else 0
    print(f"  {f.name} ({size} bytes)")

टाइप किए गए डिफ़ॉल्ट के साथ पर्यावरण चर से एप्लिकेशन कॉन्फ़िग पढ़ना, और संरचित एक्सेस लॉग एंट्रीज़ को newline-delimited JSON के रूप में लिखना:

python
import os
import json
from datetime import datetime
from pathlib import Path

def load_env_config() -> dict:
    return {
        "debug": os.environ.get("DEBUG", "false").lower() == "true",
        "port": int(os.environ.get("PORT", "8080")),
        "log_level": os.environ.get("LOG_LEVEL", "INFO"),
    }

def write_access_log(method: str, path: str, status: int) -> None:
    log_dir = Path("logs")
    log_dir.mkdir(exist_ok=True)
    entry = {
        "ts": datetime.now().isoformat(),
        "method": method,
        "path": path,
        "status": status,
    }
    with open(log_dir / "access.jsonl", "a") as f:
        f.write(json.dumps(entry) + "\n")

config = load_env_config()
print(f"पोर्ट {config['port']} पर शुरू किया जा रहा है, debug={config['debug']}")
write_access_log("GET", "/users", 200)

Newline-delimited JSON (.jsonl) एक सामान्य लॉग प्रारूप है: प्रत्येक पंक्ति एक वैध JSON ऑब्जेक्ट है, जो इसे स्ट्रीम, अपेंड, और पंक्ति दर पंक्ति पार्स करने के लिए सीधा बनाता है पूरी फ़ाइल को लोड किए बिना।