GeeksforGeeks
hantera resurser: i alla programmeringsspråk är användningen av resurser som filoperationer eller databasanslutningar mycket vanligt. Men dessa resurser är begränsade i utbudet. Därför ligger huvudproblemet i att se till att frigöra dessa resurser efter användning. Om de inte släpps kommer det att leda till resursläckage och kan orsaka att systemet antingen saktar ner eller kraschar. Det skulle vara till stor hjälp om användaren har en mekanism för automatisk installation och nedkoppling av resurser.I Python kan det uppnås genom användning av kontexthanterare som underlättar korrekt hantering av resurser. Det vanligaste sättet att utföra filoperationer är att använda med nyckelordet som visas nedan:
with
open
(
"test.txt"
) as f:
data
=
f.read()
Let’s take the example of file förvaltning. När en fil öppnas förbrukas en filbeskrivning som är en begränsad resurs. Endast ett visst antal filer kan öppnas av en process i taget. Följande program visar det.
file_descriptors
=
for
x
in
range
(
100000
):
file_descriptors.append(
open
(
'test.txt'
,
'w'
))
utgång:
Traceback (most recent call last): File "context.py", line 3, in OSError: Too many open files: 'test.txt'
ett felmeddelande som säger att för många filer är öppna. Ovanstående exempel är ett fall av filbeskrivningsläckage. Det händer eftersom det finns för många öppna filer och de är inte stängda. Det kan finnas chanser där en programmerare kan glömma att stänga en öppnad fil.
hantera resurser med hjälp av context manager :
Antag att ett kodblock ger upphov till ett undantag eller om det har en komplex algoritm med flera returvägar blir det besvärligt att stänga en fil på alla platser.
generellt på andra språk när du arbetar med filer try-except-finally används för att säkerställa att filresursen är stängd efter användning även om det finns ett undantag.Python ger ett enkelt sätt att hantera resurser: Context Managers. Nyckelordet med används. När det utvärderas bör det resultera i ett objekt som utför kontexthantering. Kontexthanterare kan skrivas med klasser eller funktioner(med dekoratörer).
skapa en Kontexthanterare:
När du skapar kontexthanterare med klasser måste användaren se till att klassen har metoderna: __enter__() och __exit__(). _ _ Enter _ _ () returnerar resursen som behöver hanteras och __exit__() returnerar inget annat än utför rensningsoperationerna.
först kan vi skapa en enkel klass som heter ContextManager för att förstå den grundläggande strukturen för att skapa kontexthanterare med hjälp av klasser, som visas nedan:
class
ContextManager():
def
__init__(
self
):
print
(
'init method called'
)
def
__enter__(
self
):
print
(
'enter method called'
)
return
self
def
__exit__(
self
, exc_type, exc_value, exc_traceback):
print
(
'exit method called'
)
with ContextManager() as manager:
print
(
'with statement block'
)
Output:
init method calledenter method calledwith statement blockexit method called
i detta fall skapas ett ContextManager-objekt. Detta tilldelas variabeln efter as-nyckelordet dvs chef. När du kör ovanstående program körs följande i följd:
- __init__()
- __enter__()
- uttalande kropp (kod inuti med block)
- __exit__()
filhantering med hjälp av context manager :
låt oss tillämpa ovanstående koncept för att skapa en klass som hjälper till med filresurshantering.FileManager-klassen hjälper till att öppna en fil, skriva / läsa innehåll och sedan stänga den.
class
FileManager():
def
__init__(
self
, filename, mode):
self
.filename
=
filename
self
.mode
=
mode
self
.
file
=
None
def
__enter__(
self
):
self
.
file
=
open
(
self
.filename,
self
.mode)
return
self
.
file
def
__exit__(
self
, exc_type, exc_value, exc_traceback):
self
.
file
.close()
with FileManager(
'test.txt'
,
'w'
) as f:
f.write(
'Test'
)
print
(f.closed)
utgång:
True
filhantering med hjälp av context manager och med uttalande :
Vid körning av med-blocket sker följande åtgärder i följd:
- ett Filmanager-objekt skapas med test.txt som filnamn och w (skriv) som Läge När __init__ – metoden körs.
- metoden __enter _ _ öppnar testet.txt-fil i skrivläge(setup operation) och returnerar filemanager-objektet till variabel f.
- texten ’Test’ skrivs in i filen.
- metoden __exit__ tar hand om att stänga filen när du lämnar med-blocket(nedkoppling).
när print (f.closed) körs är utmatningen sann eftersom filhanteraren redan har tagit hand om att stänga filen som annars behövde göras uttryckligen.
databasanslutningshantering med hjälp av context manager:
Låt oss skapa ett enkelt databasanslutningshanteringssystem. Antalet databasanslutningar som kan öppnas åt gången är också begränsat(precis som filbeskrivningar). Därför är kontexthanterare användbara för att hantera anslutningar till databasen eftersom det kan finnas chanser att programmeraren kan glömma att stänga anslutningen.
from
pymongo
import
MongoClient
class
MongoDBConnectionManager():
def
__init__(
self
, hostname, port):
self
.hostname
=
hostname
self
.port
=
port
self
.connection
=
None
def
__enter__(
self
):
self
.connection
=
MongoClient(
self
.hostname,
self
.port)
return
self
def
__exit__(
self
, exc_type, exc_value, exc_traceback):
self
.connection.close()
with MongoDBConnectionManager(
'localhost'
,
'27017'
) as mongo:
collection
=
mongo.connection.SampleDb.test
data
=
collection.find({
'_id'
:
1
})
print
(data.get(
'name'
))
databasanslutningshantering med hjälp av context Manager och med uttalande:
Vid körning av med-blocket sker följande åtgärder i följd:
- ett mongodbconnectionmanager-objekt skapas med localhost som värdnamn och 27017 som port när __init__ – metoden körs.
- metoden __enter _ _ öppnar mongodb-anslutningen och returnerar objektet MongoDBConnectionManager till variabel mongo.
- testsamlingen i SampleDb-databasen nås och dokumentet med _id=1 hämtas. Dokumentets namnfält skrivs ut.
- metoden __exit__ tar hand om att stänga anslutningen när du lämnar med-blocket (nedkoppling).