مرکزی مواد پر جائیں
ماڈیول 9 · سبق 3 از 4کورس میں 35/36~12 min
ماڈیول اسباق (3/4)

سیاق و سباق مینیجر: اور __enter__/__exit__ کے ساتھ

سیاق و سباق کا مینیجر ایک ایسی چیز ہے جسے آپ with کے ساتھ استعمال کرتے ہیں۔ اس کی ضمانت دیتا ہے۔ بعض سیٹ اپ/کلین اپ آپریشنز ہمیشہ ہوتے ہیں، یہاں تک کہ جب غلطیاں واقع ہوں۔ کینونیکل مثال: فائل کو کھولنا اور بند کرنا۔

with پیٹرن

Python
with open("note.txt", "w") as f:
    f.write("ciao")
# qui f è già chiuso, anche se write() ha sollevato un'eccezione

سادہ انگریزی میں: "** کے ساتھ** وسائل X کو f کے طور پر کھولیں، یہ کریں۔ جب ہو جائے۔ (جو بھی ہوتا ہے)، X کو بند کریں۔" with کے بغیر آپ کو لکھنا پڑے گا۔ ایک try/finally ہر بار۔

ایک وقت میں ایک سے زیادہ

Python
with open("a.txt") as f, open("b.txt") as g:
    dati_a = f.read()
    dati_b = g.read()

اپنے سیاق و سباق کے مینیجر (کلاس) کو لکھنا

آپ کو دو ڈنڈر طریقوں کی وضاحت کرنے کی ضرورت ہے: __enter__ اور __exit__۔

Python
class Timer:
    def __enter__(self):
        import time
        self.t0 = time.perf_counter()
        return self  # è l'oggetto che finisce dopo "as"
    def __exit__(self, exc_type, exc_value, traceback):
        import time
        self.elapsed = time.perf_counter() - self.t0
        # ritornare True ingoia l'eccezione; di solito non lo vuoi
        return False

with Timer() as t:
    sum(range(10**6))
t.elapsed  # quanto è durato
  • بلاک میں داخل ہونے پر __enter__(self) کو بلایا جاتا ہے۔ لوٹی ہوئی قدر وہ ہے جو آپ کو as کے بعد ملتی ہے۔
  • __exit__(self, exc_type, exc_value, tb) باہر نکلنے پر بلایا جاتا ہے (ہمیشہ)۔ اگر یہ True لوٹاتا ہے، تو کوئی بھی استثناء دب جاتا ہے۔

شارٹ کٹ: @contextmanager

contextlib.contextmanager آپ کو سیاق و سباق کے مینیجر کو بطور a لکھنے دیتا ہے۔ جنریٹر فنکشن:

Python
from contextlib import contextmanager

@contextmanager
def timer():
    import time
    t0 = time.perf_counter()
    try:
        yield  # qui sta il blocco "with"
    finally:
        elapsed = time.perf_counter() - t0
        print(f"durata: {elapsed:.4f}s")

with timer():
    sum(range(10**6))

کوڈ پہلے yield ہے __enter__، کوڈ بعد ہے __exit__۔ try/finally صفائی کی ضمانت دیتا ہے یہاں تک کہ خرابیاں ہونے پر۔

suppress : ایک استثناء کو نظر انداز کرنا

Python
from contextlib import suppress

with suppress(FileNotFoundError):
    open("forse-non-esiste.txt").read()
# se il file non c'è, nessun errore propaga

نقصان: with صرف ان اشیاء کے لیے جو اس کی حمایت کرتے ہیں۔

Python
x = 42
with x:  # AttributeError: __enter__
    ...

@contextmanager کے ساتھ سیاق و سباق کے مینیجرز کو لکھنا

معیاری لائبریری کا contextlib ماڈیول __enter__ اور __enter__ اور __enter__ اور __enter__ کے طریقہ کار کو نافذ کرنے والی وربوز کلاسز لکھنے کے بجائے، جنریٹر فنکشنز کا استعمال کرتے ہوئے سیاق و سباق کے مینیجر بنانے کے لئے ایک انتہائی آسان ڈیکوریٹر برآمد کرتا ہے۔ آپ صرف ایک جنریٹر فنکشن لکھتے ہیں جو ایک yield استعمال کرتا ہے:

Python
from contextlib import contextmanager

@contextmanager
def manage_resource():
    # __enter__ code
    yield resource
    # __exit__ code

خود ہی آزمائیں۔

ورزش#python.m9.l3.e1
کوششیں: 0لوڈ ہو رہا ہے…

ValueError کو نظر انداز کرتے ہوئے int('non-numero') کو آزمانے کے لیے contextlib.suppress استعمال کریں۔ بلاک تفویض کرنے کے بعد `ok = True`۔ `ٹھیک` کا اندازہ لگائیں۔

ایڈیٹر لوڈ ہو رہا ہے…
اشارہ دکھائیں۔

suppress(ValueError) صرف ValueError کو نگلتا ہے۔

3 کوششوں کے بعد حل دستیاب ہے۔

ورزش کا جائزہ لیں۔

ورزش#python.m9.l3.e2
کوششیں: 0لوڈ ہو رہا ہے…

@contextmanager کے ساتھ ایک سیاق و سباق کے مینیجر `collect` لکھیں جو ایک خالی فہرست حاصل کرے اور باہر نکلنے پر اسے ٹوپل میں بدل دے (اسے پرنٹ کریں)۔ اسے بلاک کے اندر کی فہرست میں 1، 2، 3 شامل کرنے کے لیے استعمال کریں۔ آخر میں، `len(collection)` کا اندازہ کریں جہاں `collection` حاصل شدہ فہرست ہے۔

ایڈیٹر لوڈ ہو رہا ہے…
اشارہ دکھائیں۔

بلاک کے اندر فہرست کو بے نقاب کرنے کے لیے آئٹمز حاصل کریں۔

3 کوششوں کے بعد حل دستیاب ہے۔

اضافی چیلنج

ورزش#python.m9.l3.e3
کوششیں: 0لوڈ ہو رہا ہے…

Write a custom context manager using the `@contextmanager` decorator from `contextlib`. The context manager must be named `mock_session`. Upon entry, it must append `'start'` to a global list `log_list = []`, yield control using `yield`, and upon exit append `'stop'`. Finally, evaluate `log_list` after using the context manager with `with mock_session():`.

ایڈیٹر لوڈ ہو رہا ہے…
اشارہ دکھائیں۔

'اسٹاپ' شامل کرنے سے پہلے عمل کو معطل کرنے کے لیے mock_session کے اندر پیداوار کا استعمال کریں۔

3 کوششوں کے بعد حل دستیاب ہے۔