logo

met verklaring in Python

In Python, met verklaring wordt gebruikt bij het afhandelen van uitzonderingen om de code schoner en veel leesbaarder te maken. Het vereenvoudigt het beheer van algemene bronnen zoals bestandsstromen. Bekijk het volgende codevoorbeeld om te zien hoe het gebruik van de instructie with de code schoner maakt.

Python3




strsep c





# file handling> # 1) without using with statement> file> => open>(>'file_path'>,>'w'>)> file>.write(>'hello world !'>)> file>.close()> # 2) without using with statement> file> => open>(>'file_path'>,>'w'>)> try>:> >file>.write(>'hello world'>)> finally>:> >file>.close()>



>

>

Python3




# using with statement> with>open>(>'file_path'>,>'w'>) as>file>:> >file>.write(>'hello world !'>)>

>

>

Merk op dat het, in tegenstelling tot de eerste twee implementaties, niet nodig is om file.close() aan te roepen bij gebruik van een statement. De with-verklaring zelf zorgt voor een juiste verwerving en vrijgave van middelen. Een uitzondering tijdens de file.write()-aanroep in de eerste implementatie kan ervoor zorgen dat het bestand niet correct wordt afgesloten, wat verschillende bugs in de code kan introduceren, dat wil zeggen dat veel wijzigingen in bestanden pas van kracht worden als het bestand correct is gesloten. De tweede benadering in het bovenstaande voorbeeld zorgt voor alle uitzonderingen, maar het gebruik van de instructie with maakt de code compact en veel leesbaarder. Met statement helpt u dus bugs en lekken te voorkomen door ervoor te zorgen dat een bron correct wordt vrijgegeven wanneer de code die de bron gebruikt, volledig is uitgevoerd. De instructie with wordt in de volksmond gebruikt bij bestandsstreams, zoals hierboven weergegeven, en bij Locks, sockets, subprocessen en telnets enz.

Ondersteuning van de with-instructie in door de gebruiker gedefinieerde objecten

Er is niets speciaals in open() dat het bruikbaar maakt met de instructie with en dezelfde functionaliteit kan worden geboden in door de gebruiker gedefinieerde objecten. Ondersteuning met verklaringen in uw objecten zorgt ervoor dat u nooit een bron open laat. Om de instructie With in door de gebruiker gedefinieerde objecten te gebruiken, hoeft u alleen de methoden __enter__() en __exit__() toe te voegen aan de objectmethoden. Beschouw het volgende voorbeeld voor verdere verduidelijking.

Python3


afbeelding uitlijnen met css



# a simple file writer object> class> MessageWriter(>object>):> >def> __init__(>self>, file_name):> >self>.file_name>=> file_name> > >def> __enter__(>self>):> >self>.>file> => open>(>self>.file_name,>'w'>)> >return> self>.>file> >def> __exit__(>self>,>*>args):> >self>.>file>.close()> # using with statement with MessageWriter> with MessageWriter(>'my_file.txt'>) as xfile:> >xfile.write(>'hello world'>)>

>

>

Laten we de bovenstaande code eens bekijken. Als het u opvalt: wat volgt op het trefwoord with is de constructor van MessageWriter. Zodra de uitvoering de context van de with-instructie binnengaat, wordt er een MessageWriter-object gemaakt en roept Python vervolgens de methode __enter__() aan. In deze __enter__() methode initialiseert u de bron die u in het object wilt gebruiken. Deze __enter__() methode moet altijd een descriptor van de verkregen bron retourneren. Wat zijn resourcedescriptoren? Dit zijn de handvatten die door het besturingssysteem worden geboden om toegang te krijgen tot de gevraagde bronnen. In het volgende codeblok is bestand een descriptor van de bestandsstroombron.

Python




linkse join versus rechtse join
file> => open>(>'hello.txt'>)>

>

>

In het hierboven gegeven MessageWriter-voorbeeld maakt de methode __enter__() een bestandsdescriptor en retourneert deze. De naam xfile wordt hier gebruikt om te verwijzen naar de bestandsdescriptor die wordt geretourneerd door de methode __enter__(). Het codeblok dat de verkregen bron gebruikt, wordt in het blok van de with-instructie geplaatst. Zodra de code in het with-blok wordt uitgevoerd, wordt de methode __exit__() aangeroepen. Alle verworven bronnen worden vrijgegeven in de __exit__() methode. Dit is hoe we de instructie with gebruiken met door de gebruiker gedefinieerde objecten. Deze interface van __enter__() en __exit__() methoden die ondersteuning biedt voor instructies in door de gebruiker gedefinieerde objecten, wordt genoemd Contextmanager .

De contextlib-module

Een op klassen gebaseerde contextmanager, zoals hierboven weergegeven, is niet de enige manier om de instructie with in door de gebruiker gedefinieerde objecten te ondersteunen. De contextlib module biedt nog een paar abstracties die zijn gebouwd op de basiscontextmanagerinterface. Hier ziet u hoe we de contextmanager voor het MessageWriter-object kunnen herschrijven met behulp van de contextlib-module.

Python3




TCP IP-model

from> contextlib>import> contextmanager> class> MessageWriter(>object>):> >def> __init__(>self>, filename):> >self>.file_name>=> filename> >@contextmanager> >def> open_file(>self>):> >try>:> >file> => open>(>self>.file_name,>'w'>)> >yield> file> >finally>:> >file>.close()> # usage> message_writer>=> MessageWriter(>'hello.txt'>)> with message_writer.open_file() as my_file:> >my_file.write(>'hello world'>)>

>

>

In dit codevoorbeeld is het vanwege de opbrengst statement in zijn definitie is de functie open_file() a generatorfunctie . Wanneer deze functie open_file() wordt aangeroepen, wordt er een resourcedescriptor met de naam file gemaakt. Deze resourcedescriptor wordt vervolgens doorgegeven aan de beller en wordt hier weergegeven door de variabele my_file. Nadat de code in het with-blok is uitgevoerd, keert de programmabesturing terug naar de functie open_file(). De functie open_file() hervat de uitvoering ervan en voert de code uit na de yield-instructie. Dit deel van de code dat verschijnt na de rendementsverklaring geeft de verworven bronnen vrij. De @contextmanager hier is een decorateur . De vorige, op klassen gebaseerde implementatie en deze op generator gebaseerde implementatie van contextmanagers zijn intern hetzelfde. Hoewel dit laatste beter leesbaar lijkt, vereist het de kennis van generatoren, decorateurs en opbrengst.