ప్రధాన కంటెంట్‌కు వెళ్లండి
మాడ్యూల్ 9 · 4లో పాఠం 3కోర్సులో 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 ఒక సందర్భ నిర్వాహికిని వ్రాయడానికి మిమ్మల్ని అనుమతిస్తుంది జనరేటర్ ఫంక్షన్:

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 శుభ్రపరచడానికి హామీ ఇస్తుంది.

అణచివేయు: మినహాయింపును విస్మరించండి

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__ మరియు __AGYTOK_IN పద్ధతులను అమలు చేసే వెర్బోస్ క్లాస్‌లను వ్రాయడానికి బదులుగా, జనరేటర్ ఫంక్షన్‌లను ఉపయోగించి కాంటెక్స్ట్ మేనేజర్‌లను సృష్టించడానికి @contextmanager అనే అత్యంత అనుకూలమైన డెకరేటర్‌ను ఎగుమతి చేస్తుంది. మీరు కేవలం ఒక 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`ని కేటాయించండి. `సరే`ని మూల్యాంకనం చేయండి.

ఎడిటర్ లోడ్ అవుతోంది…
సూచనను చూపించు

అణచివేయు (ValueError) విలువ దోషాన్ని మాత్రమే మింగేస్తుంది.

3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది

వ్యాయామం సమీక్షించండి

వ్యాయామం#python.m9.l3.e2
ప్రయత్నాలు: 0లోడ్ అవుతోంది...

@contextmanagerతో కాంటెక్స్ట్ మేనేజర్ `కలెక్ట్`ని వ్రాయండి, అది ఖాళీ జాబితాను అందిస్తుంది మరియు నిష్క్రమించిన తర్వాత దాన్ని టుపుల్‌గా మారుస్తుంది (దీన్ని ప్రింట్ చేయండి). బ్లాక్ లోపల జాబితాకు 1, 2, 3 జోడించడానికి దీన్ని ఉపయోగించండి. చివర్లో, `లెన్(కలెక్షన్)`ని మూల్యాంకనం చేయండి, ఇక్కడ `సేకరణ` అందించబడిన జాబితా.

ఎడిటర్ లోడ్ అవుతోంది…
సూచనను చూపించు

బ్లాక్‌లో ఉన్న జాబితాను బహిర్గతం చేయడానికి అంశాలను అందించండి.

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 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది