Python Core (Advanced)
Iterators, generators, exceptions, files, modules
यह क्यों मायने रखता है
यही वह असली-दुनिया का औज़ार-बक्सा है जो Python को बड़े पैमाने पर उत्पादक बनाता है।
मूल विचार
Iterables आपको डेटा को आलस से (lazily) स्ट्रीम करने देते हैं (विशाल / अनंत sequences के लिए अच्छा)। Generators एक iterator लिखने का सबसे सस्ता तरीक़ा हैं। Exceptions error जाँच बिखेरे बिना विफलता का संकेत देते हैं। Context managers (with) सफ़ाई की गारंटी देते हैं।
आज़माकर देखिए
yield के साथ generators — मानों को आलस से बनाएँ:
def fib():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
g = fib()
first_ten = [next(g) for _ in range(10)]
print(first_ten)
Generator expressions बनाम list comprehensions — वही syntax, आलसी मूल्यांकन:
# Total memory: O(1) for the generator, O(n) for the list
nums = range(1_000_000)
total = sum(x * x for x in nums if x % 3 == 0)
print("sum of squares of multiples of 3:", total)
Exceptions + try/except/else/finally:
def safe_div(a, b):
try:
result = a / b
except ZeroDivisionError:
return None
except TypeError as e:
return f"type error: {e}"
else:
return result
finally:
# runs no matter what — log, close files, etc.
pass
print(safe_div(10, 2))
print(safe_div(10, 0))
print(safe_div(10, "x"))
Standard library की ज़रूरी चीज़ें
आपको शायद ही कभी data structures शून्य से लिखने पड़ते हैं — standard library में तेज़ संस्करण मौजूद हैं:
collections:deque,defaultdict,Counteritertools:accumulate,product,permutationsmath,statistics,random
Typing hints + dataclasses
Type hints इरादे को दस्तावेज़ करते हैं (और editors / type checkers को शक्ति देते हैं); @dataclass आपके लिए वह दोहरावदार __init__ / __repr__ लिख देता है:
from dataclasses import dataclass
def add(a: int, b: int) -> int:
return a + b
@dataclass
class Point:
x: int
y: int
झटपट जाँच
- प्र:
with open(...)क्यों इस्तेमाल करें? उ: यह file को अपने-आप बंद कर देता है।
छोटे अभ्यास
- एक generator लिखिए जो सम numbers yield करे।
- एक
KeyErrorको सुरक्षित ढंग से पकड़िए। - एक file पढ़िए और उसकी पंक्तियाँ गिनिए।
क्या करें और क्या न करें
- करें बड़े डेटा स्ट्रीम के लिए generators इस्तेमाल करें।
- करें विशिष्ट exceptions पकड़ें।
- न करें files खुली न छोड़ें।
- न करें exceptions को चुपचाप न निगलें।
और गहराई में — कस्टम iteration
कोई भी object जो __iter__ (iterator लौटाता है) और __next__ (अगला मान देता है या StopIteration raise करता है) लागू करता है, वह for loop में काम करता है:
class CounterIter:
def __init__(self, n):
self.n = n
self.i = 0
def __iter__(self):
return self
def __next__(self):
if self.i >= self.n:
raise StopIteration
val = self.i
self.i += 1
return valआम ग़लतियाँ
- ग़लती: हर जगह नंगा
except:इस्तेमाल करना। समाधान: विशिष्ट errors पकड़ें। - ग़लती: किसी generator में
yieldभूल जाना। समाधान: मानों को स्ट्रीम करने के लिएyieldइस्तेमाल करें। - ग़लती: विशाल files को
read()से पढ़ना। समाधान: एक-एक पंक्ति करके iterate करें।
मुख्य बातें
- Generators (
yield) स्थिर memory के साथ iterators बनाते हैं। - बड़े inputs के लिए
sum([x*x for x in nums])के बजाय generator expressionsum(x*x for x in nums)इस्तेमाल करें। - अपेक्षित विफलताओं पर control flow के लिए
try/except; अनपेक्षित errors को ऊपर उठने दें। with open(path) as f:सही मुहावरा है —f.close()की गारंटी होती है।collections/itertoolsआपको तेज़, परखे-हुए building blocks देते हैं।