Zoeken…


Invoering

Als het gaat om het opslaan, lezen of communiceren van gegevens, is werken met de bestanden van een besturingssysteem zowel noodzakelijk als gemakkelijk met Python. In tegenstelling tot andere talen waar bestandsinvoer en -uitvoer complexe lees- en schrijfobjecten vereisen, vereenvoudigt Python het proces waarbij alleen opdrachten nodig zijn om het bestand te openen, lezen / schrijven en sluiten. In dit onderwerp wordt uitgelegd hoe Python kan communiceren met bestanden op het besturingssysteem.

Syntaxis

  • file_object = open (bestandsnaam [, access_mode] [, buffering])

parameters

Parameter Details
bestandsnaam het pad naar uw bestand of, als het bestand zich in de werkmap bevindt, de bestandsnaam van uw bestand
access_mode een tekenreekswaarde die bepaalt hoe het bestand wordt geopend
buffering een geheel getal dat wordt gebruikt voor optionele lijnbuffering

Opmerkingen

Het vermijden van de platformonafhankelijke coderingshel

Wanneer u Pythons ingebouwde open() , is het best om altijd het encoding als u van plan bent om uw code platformonafhankelijk uit te voeren. De reden hiervoor is dat de standaardcodering van een systeem verschilt van platform tot platform.

Hoewel linux systemen inderdaad utf-8 als standaard gebruiken, is dit niet noodzakelijkerwijs waar voor MAC en Windows.

Probeer het volgende om de standaardcodering van een systeem te controleren:

import sys
sys.getdefaultencoding()

van elke python-tolk.

Daarom is het verstandig om altijd een codering te scheiden, om ervoor te zorgen dat de tekenreeksen waarmee u werkt zijn gecodeerd zoals u denkt dat ze zijn, waardoor compatibiliteit tussen platforms wordt gewaarborgd.

with open('somefile.txt', 'r', encoding='UTF-8') as f:
    for line in f:
        print(line)

Bestandsmodi

Er zijn verschillende modi kunt u een bestand met te openen, die door de mode parameter. Waaronder:

  • 'r' - leesmodus. De standaard. Hiermee kunt u alleen het bestand lezen en niet wijzigen. Bij gebruik van deze modus moet het bestand bestaan.

  • 'w' - schrijfmodus. Er wordt een nieuw bestand gemaakt als het niet bestaat, anders wordt het bestand gewist en kunt u ernaar schrijven.

  • 'a' - append-modus. Het schrijft gegevens naar het einde van het bestand. Het bestand wordt niet gewist en het bestand moet bestaan voor deze modus.

  • 'rb' - leesmodus in binair. Dit is vergelijkbaar met r behalve dat het lezen wordt geforceerd in binaire modus. Dit is ook een standaardkeuze.

  • 'r+' - leesmodus plus schrijfmodus tegelijkertijd. Hiermee kunt u tegelijkertijd bestanden lezen en schrijven zonder r en w te hoeven gebruiken.

  • 'rb+' - lees- en schrijfmodus in binair. Hetzelfde als r+ behalve dat de gegevens binair zijn

  • 'wb' - schrijfmodus in binair. Hetzelfde als w behalve dat de gegevens binair zijn.

  • 'w+' - schrijf- en leesmodus. Precies hetzelfde als r+ maar als het bestand niet bestaat, wordt er een nieuw gemaakt. Anders wordt het bestand overschreven.

  • 'wb+' - schrijf- en leesmodus in binaire modus. Hetzelfde als w+ maar de gegevens zijn binair.

  • 'ab' - toevoegen in binaire modus. Vergelijkbaar met a uitzondering dat de gegevens binair zijn.

  • 'a+' - toevoegen en lezen. Vergelijkbaar met w+ omdat het een nieuw bestand maakt als het bestand niet bestaat. Anders bevindt de bestandspointer zich aan het einde van het bestand, als deze bestaat.

  • 'ab+' - toevoeg- en leesmodus in binair. Hetzelfde als a+ behalve dat de gegevens binair zijn.

     with open(filename, 'r') as f:
         f.read()
     with open(filename, 'w') as f:
         f.write(filedata)
     with open(filename, 'a') as f:
         f.write('\n' + newdata)
    
r r + w w + een a +
Lezen
Schrijven
Maakt bestand
Wist bestand
Startpositie Begin Begin Begin Begin Einde Einde

Python 3 heeft een nieuwe modus toegevoegd voor exclusive creation zodat u niet per ongeluk een bestaand bestand kunt afkappen of overschrijven.

  • 'x' - open voor exclusieve creatie, zal FileExistsError verhogen als het bestand al bestaat
  • 'xb' - open voor exclusieve creatie schrijfmodus in binair. Hetzelfde als x behalve dat de gegevens binair zijn.
  • 'x+' - lees- en schrijfmodus. Vergelijkbaar met w+ omdat het een nieuw bestand maakt als het bestand niet bestaat. Anders wordt FileExistsError verhoogd.
  • 'xb+' - schrijf- en leesmodus. Precies hetzelfde als x+ maar de gegevens zijn binair
X x +
Lezen
Schrijven
Maakt bestand
Wist bestand
Startpositie Begin Begin

Laat iemand de open code van uw bestand op een meer pythonische manier schrijven:

Python 3.x 3.3
try:
    with open("fname", "r") as fout:
        # Work with your open file
except FileExistsError:
    # Your error handling goes here

In Python 2 zou je zoiets hebben gedaan

Python 2.x 2.0
import os.path
if os.path.isfile(fname):
    with open("fname", "w") as fout:
        # Work with your open file
else:
    # Your error handling goes here

Een bestand regel voor regel lezen

De eenvoudigste manier om een bestand regel voor regel te herhalen:

with open('myfile.txt', 'r') as fp:
    for line in fp:
        print(line)

readline() zorgt voor readline() controle over regel-voor-regel iteratie. Het onderstaande voorbeeld is gelijk aan het bovenstaande:

with open('myfile.txt', 'r') as fp:
    while True:
        cur_line = fp.readline()
        # If the result is an empty string
        if cur_line == '':
            # We have reached the end of the file
            break
        print(cur_line)

Het samen gebruiken van de for loop iterator en readline () wordt als een slechte gewoonte beschouwd.

Meer gebruikelijk wordt de methode readlines() gebruikt om een iterabele verzameling regels van het bestand op te slaan:

with open("myfile.txt", "r") as fp:
    lines = fp.readlines()
for i in range(len(lines)):
    print("Line " + str(i) + ": " + line)

Dit zou het volgende afdrukken:

Regel 0: hallo

Regel 1: wereld

De volledige inhoud van een bestand ophalen

De voorkeursmethode voor bestands-i / o is om het trefwoord with te gebruiken. Dit zorgt ervoor dat de bestandsingang wordt gesloten zodra het lezen of schrijven is voltooid.

with open('myfile.txt') as in_file:
    content = in_file.read()

print(content)

of, om het bestand handmatig te sluiten, kunt u afzien with en eenvoudig zelf close aanroepen:

in_file = open('myfile.txt', 'r')
content = in_file.read()
print(content)
in_file.close()

Houd er rekening mee dat zonder het gebruik with instructie with , u het bestand per ongeluk open kunt houden voor het geval zich een onverwachte uitzondering voordoet:

in_file = open('myfile.txt', 'r')
raise Exception("oops")
in_file.close()  # This will never be called

Naar een bestand schrijven

with open('myfile.txt', 'w') as f:
    f.write("Line 1")
    f.write("Line 2")
    f.write("Line 3")
    f.write("Line 4")

Als u myfile.txt opent, ziet u dat de inhoud ervan is:

Lijn 1Lijn 2Lijn 3Lijn 4

Python voegt niet automatisch regeleinden toe, dit moet u handmatig doen:

with open('myfile.txt', 'w') as f:
    f.write("Line 1\n")
    f.write("Line 2\n")
    f.write("Line 3\n")
    f.write("Line 4\n")

Lijn 1
Lijn 2
Regel 3
Regel 4

Gebruik os.linesep als een os.linesep bij het schrijven van bestanden die in tekstmodus zijn geopend (de standaardinstelling); gebruik in plaats daarvan \n .

Als u een codering wilt opgeven, voegt u eenvoudig de encoding aan de open functie:

with open('my_file.txt', 'w', encoding='utf-8') as f:
    f.write('utf-8 text')

Het is ook mogelijk om de afdrukopdracht te gebruiken om naar een bestand te schrijven. De werking is verschillend in Python 2 versus Python 3, maar het concept is hetzelfde omdat u de uitvoer die naar het scherm zou zijn gegaan kunt nemen en in plaats daarvan naar een bestand kunt sturen.

Python 3.x 3.0
with open('fred.txt', 'w') as outfile:
    s = "I'm Not Dead Yet!"
    print(s) # writes to stdout
    print(s, file = outfile) # writes to outfile

    #Note: it is possible to specify the file parameter AND write to the screen
    #by making sure file ends up with a None value either directly or via a variable
    myfile = None
    print(s, file = myfile) # writes to stdout
    print(s, file = None)   # writes to stdout

In Python 2 zou je zoiets hebben gedaan

Python 2.x 2.0
outfile = open('fred.txt', 'w')
s = "I'm Not Dead Yet!"
print s   # writes to stdout
print >> outfile, s   # writes to outfile

In tegenstelling tot de schrijffunctie, voegt de afdrukfunctie automatisch regeleinden toe.

Inhoud van het ene bestand naar een ander bestand kopiëren

with open(input_file, 'r') as in_file, open(output_file, 'w') as out_file:
    for line in in_file:
        out_file.write(line)
  • De shutil gebruiken:
import shutil
shutil.copyfile(src, dst)

Controleer of er een bestand of pad bestaat

Gebruik de EAFP- coderingsstijl en try te openen.

import errno

try:
    with open(path) as f:
        # File exists
except IOError as e:
    # Raise the exception if it is not ENOENT (No such file or directory)
    if e.errno != errno.ENOENT:
        raise
    # No such file or directory

Dit voorkomt ook race-omstandigheden als een ander proces het bestand tussen de controle en wanneer het wordt gebruikt heeft verwijderd. Deze raceconditie kan in de volgende gevallen voorkomen:

  • Met behulp van de os module:

    import os
    os.path.isfile('/path/to/some/file.txt')
    
Python 3.x 3.4
  • pathlib :

    import pathlib
    path = pathlib.Path('/path/to/some/file.txt')
    if path.is_file():
        ...
    

Om te controleren of een bepaald pad bestaat of niet, kunt u de bovenstaande EAFP-procedure volgen of het pad expliciet controleren:

import os
path = "/home/myFiles/directory1"

if os.path.exists(path):
    ## Do stuff

Een directorystructuur kopiëren

import shutil
source='//192.168.1.2/Daily Reports'
destination='D:\\Reports\\Today'
shutil.copytree(source, destination)  

De doelmap mag nog niet bestaan .

Bestanden herhalen (recursief)

Gebruik os.walk om alle bestanden te herhalen, ook in submappen:

import os
for root, folders, files in os.walk(root_dir):
    for filename in files:
        print root, filename

root_dir kan "." zijn om te starten vanuit de huidige map of een ander pad om mee te beginnen.

Python 3.x 3.5

Als u ook informatie over het bestand wilt krijgen, kunt u de efficiëntere methode os.scandir als volgt gebruiken:

for entry in os.scandir(path):
   if not entry.name.startswith('.') and entry.is_file():
       print(entry.name)

Lees een bestand tussen een reeks regels

Laten we aannemen dat u alleen tussen enkele specifieke regels van een bestand wilt herhalen

itertools kunt u itertools gebruiken

import itertools

with open('myfile.txt', 'r') as f:
    for line in itertools.islice(f, 12, 30):
        # do something here

Dit leest de regels 13 tot 20 door, zoals in python begint het indexeren vanaf 0. Dus lijnnummer 1 wordt geïndexeerd als 0

Zoals ook wat extra regels kan lezen door gebruik te maken van het next() sleutelwoord hier.

En wanneer u het bestandsobject als een iterabel gebruikt, gebruikt u de readline() hier niet, omdat de twee technieken voor het doorlopen van een bestand niet mogen worden gemengd

Toegang tot willekeurige bestanden met mmap

Met behulp van de mmap module kan de gebruiker willekeurig toegang krijgen tot locaties in een bestand door het bestand in het geheugen toe te wijzen. Dit is een alternatief voor het gebruik van normale bestandsbewerkingen.

import mmap

with open('filename.ext', 'r') as fd:
    # 0: map the whole file
    mm = mmap.mmap(fd.fileno(), 0)

    # print characters at indices 5 through 10
    print mm[5:10]

    # print the line starting from mm's current position
    print mm.readline()

    # write a character to the 5th index
    mm[5] = 'a'

    # return mm's position to the beginning of the file
    mm.seek(0)

    # close the mmap object
    mm.close()

Tekst in een bestand vervangen

import fileinput

replacements = {'Search1': 'Replace1',
                'Search2': 'Replace2'}

for line in fileinput.input('filename.txt', inplace=True):
    for search_for in replacements:
        replace_with = replacements[search_for]
        line = line.replace(search_for, replace_with)
    print(line, end='')

Controleren of een bestand leeg is

>>> import os
>>> os.stat(path_to_file).st_size == 0

of

>>> import os    
>>> os.path.getsize(path_to_file) > 0

Beide zullen echter een uitzondering genereren als het bestand niet bestaat. Om te voorkomen dat je zo'n fout moet maken, doe je dit:

import os
def is_empty_file(fpath):  
    return os.path.isfile(fpath) and os.path.getsize(fpath) > 0

die een bool waarde retourneert.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow