Bestanden lezen met Python

Introductie

Om met opgeslagen gegevens te werken, wordt bestandsafhandeling de kernkennis van elke professionele Python-programmeur. Vanaf de eerste release zijn zowel het lezen als het schrijven van gegevens naar bestanden ingebouwde Python-functies. In vergelijking met andere programmeertalen zoals C of Java, is het vrij eenvoudig en vereist het slechts een paar regels code. Verder hoeft er geen extra module geladen te worden om dat goed te doen.

In dit artikel leggen we aan de hand van voorbeelden uit hoe je bestanden kunt lezen met Python. Enkele voorbeelden zijn het regel voor regel lezen van een bestand, als een brok (een bepaald aantal regels tegelijk) en het in รฉรฉn keer lezen van een bestand. We laten u ook een manier zien om een โ€‹โ€‹specifieke regel uit het bestand te lezen, zonder het hele bestand te doorzoeken.

Basisprincipes van bestanden in Python

De gebruikelijke methoden om met bestanden te werken zijn: open() om een โ€‹โ€‹bestand te openen, seek() om de huidige positie van het bestand op de gegeven offset in te stellen, en close() om het bestandsobject te sluiten wanneer u klaar bent met het gebruik ervan. De ingebouwde open() functie retourneert een bestandshandle die een bestandsobject vertegenwoordigt dat moet worden gebruikt om toegang te krijgen tot het bestand voor lezen, schrijven of toevoegen.

Bij het openen van een bestand om te lezen, moet Python precies weten hoe het bestand met het systeem moet worden geopend. Er zijn twee toegangsmodi beschikbaar: lezen en lezen in binaire modus. De respectieve gebruikte vlaggen zijn: 'r' en 'rb', en moeten worden opgegeven bij het openen van een bestand met de ingebouwde open() functie. De eerste modus omvat de interpretatie van speciale tekens zoals "CR" (carriage return) en "LF" (linefeed) om regeleinden weer te geven, terwijl de binaire modus u in staat stelt de gegevens in onbewerkte modus te lezen - waar de gegevens worden opgeslagen zoals ze zijn zonder verdere uitleg.

Nadat u een bestand hebt geopend, wordt de open() functie zal een bestandsobject naar u terugsturen. Deze bestandsobjecten hebben methoden zoals read(), readline(), write(), tell() en seek(). Hoewel sommige bestandsobjecten (of bestandsachtige objecten) meer methoden hebben dan hier vermeld, zijn dit de meest voorkomende. Niet alle bestandsobjecten hoeven alle bestandsmethoden te implementeren.

Een bestand regel voor regel lezen

Het eerste voorbeeld is geรฏnspireerd op de twee programmeertalen - C en C++. Het is waarschijnlijk de meest intuรฏtieve benadering: open het bestand met de open() functie, lees het bestand regel voor regel met de readline() methode en voer de regel onmiddellijk na het lezen uit.

In gebruik is hier een while lus die continu uit het bestand leest zolang de readline() methode blijft gegevens retourneren. Als het einde van het bestand (EOF) is bereikt, wordt de while lus stopt en het bestandsobject wordt gesloten, waardoor de bronnen vrijkomen voor andere programma's om te gebruiken:


filename = "test.txt"

filehandle = open(filename, 'r')
while True:
    
    line = filehandle.readline()
    if not line:
        break
    print(line)


filehandle.close()

Zoals je misschien hebt opgemerkt, hebben we het bestand in dit voorbeeld expliciet geopend en gesloten. Hoewel de Python-interpreter de geopende bestanden automatisch sluit aan het einde van de uitvoering van het Python-programma, sluit het bestand expliciet via close() is een goede programmeerstijl en mag niet worden vergeten.

Als een verbetering, de handig iteratorprotocol werd geรฏntroduceerd in Python 2.3. Hiermee kunt u de readline lus:


filename = "test.txt"
for line in open(filename, 'r'):
    print(line)

In gebruik is hier een for lus in combinatie met de in iterator. De huidige lijn wordt geรฏdentificeerd met behulp van de in iterator, lees uit het bestand, en de inhoud ervan wordt uitgevoerd naar stdout. Python dekt het openen en sluiten van het bestand voor u wanneer het buiten het bereik valt. Hoewel dit inefficiรซnt is, hoeft u zich niet meer bezig te houden met bestandshandvatten.

Helaas is de bovenstaande code minder expliciet en vertrouwt deze op de interne garbagecollection van Python om het sluiten van het bestand af te handelen.

Geรฏntroduceerd in Python 2.5, de with commando kapselt het hele proces nog meer in, en behandelt ook het openen en sluiten van bestanden slechts รฉรฉn keer in het gehele codeblok:


filename = "test.txt"
with open(filename, 'r') as filehandle:
    for line in filehandle:
        print(line)

De combinatie van de with verklaring en de open() commando opent het bestand slechts รฉรฉn keer. Indien succesvol de for lus wordt uitgevoerd en de inhoud van de regel wordt afgedrukt op stdout.

Verder is het gebruik van de with verklaring heeft een bijwerking. Intern creรซert de Python-interpreter een try-finally-blok om het lezen van het bestand in te kapselen. Het volgende voorbeeld laat zien wat er in wezen intern gebeurt in Python met de with codeblokken:

try:
    filehandle = open(filename, 'r')
    
finally:
    filehandle.close()

Een bestand lezen als stukjes regel

Tot nu toe hebben we een bestand regel voor regel verwerkt. Dit is nogal traag voor grote bestanden en kan worden verbeterd door meerdere regels tegelijk te lezen. Om dat te bereiken is de islice() methode uit de itertools module in het spel komt. Het werkt ook als een iterator en retourneert een stuk gegevens dat bestaat uit: n lijnen. Aan het einde van het bestand kan het resultaat korter zijn en ten slotte zal de aanroep een lege lijst retourneren:

from itertools import islice

filename = "test.txt"

number_of_lines = 5

with open(filename, 'r') as input_file:
    lines_cache = islice(input_file, number_of_lines)
   
    for current_line in lines_cache:
        print (current_line)

Een specifieke regel uit een bestand lezen

Met behulp van de hierboven getoonde methoden kunnen we ook andere nuttige acties uitvoeren, zoals het lezen van een specifieke regel uit een bestand. Om dit te doen, maken we gebruik van een teller en drukken we de juiste regel af wanneer we die tegenkomen tijdens het doorlopen van het bestand:


filename = "test.txt"

line_number = 3
print (f"line {line_number} of {filename} is: ")

with open(filename, 'r') as filehandle:
current_line = 1
    for line in filehandle:
        if current_line == line_number:
            print(line)
            break
        current_line += 1

Dit zou eenvoudig te begrijpen moeten zijn, maar het is iets langer dan de vorige voorbeelden. Het kan worden ingekort met behulp van de lijncache module.

Het volgende voorbeeld laat zien hoe u de code kunt vereenvoudigen met behulp van de getline() methode. Als het gevraagde regelnummer buiten het bereik van geldige regels in het bestand valt, dan getline() methode retourneert in plaats daarvan een lege tekenreeks:


import linecache

filename = "test.txt"

line_number = 3

line = linecache.getline(filename, line_number)
print (f"line {line_number} of {filename}:")
print (line)

Het hele bestand in รฉรฉn keer lezen

Last but not least zullen we een heel ander geval bekijken dan het vorige voorbeeld - het in รฉรฉn keer lezen van een heel bestand.

Houd er rekening mee dat u in de meeste gevallen voldoende geheugen moet hebben om het hele bestand te lezen, aangezien tekens niet te veel ruimte in beslag nemen, maar wees moe van grote bestanden. Het volgende voorbeeld gebruikt een combinatie van de with verklaring, en de read() methode. In dit geval gebruiken we read() om de bestandsinhoud als een gegevensstroom te laden:

Bekijk onze praktische, praktische gids voor het leren van Git, met best-practices, door de industrie geaccepteerde normen en bijgevoegd spiekbriefje. Stop met Googlen op Git-commando's en eigenlijk leren het!


filename = "test.txt"

with open(filename, 'r') as filehandle:
    filecontent = filehandle.read()
    print (filecontent)

Python biedt ook de readlines() methode, die vergelijkbaar is met de readline() methode uit het eerste voorbeeld. In contrast met read(), wordt de bestandsinhoud opgeslagen in een lijst, waarbij elke regel van de inhoud een item is:


filename = "test.txt"

with open(filename, 'r') as filehandle:
    filecontent = filehandle.readlines()
    for line in filecontent:
        print (line)

Terwijl readlines() zal inhoud uit het bestand lezen totdat het EOF bereikt, houd er rekening mee dat u ook de hoeveelheid gelezen inhoud kunt beperken door de sizehint parameter, wat het aantal te lezen bytes is.

Conclusie

Zoals gewoonlijk is er meer dan รฉรฉn manier om de inhoud van een bestand te lezen. Qua snelheid vallen ze allemaal min of meer in dezelfde categorie. Welke oplossing voor u het beste werkt, hangt af van uw specifieke gebruikssituatie. We denken dat het heel nuttig is om te kijken wat er mogelijk is en vervolgens de oplossing te kiezen die het beste past.

Hoewel Python het proces van het lezen van bestanden aanzienlijk vereenvoudigt, kan het soms nog steeds lastig worden, in welk geval ik je zou aanraden een kijkje te nemen in de officiรซle Python-documentatie voor meer info.

Tijdstempel:

Meer van Stapelmisbruik