Python Language
Bestanden en mappen I / O
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 metr
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 zonderr
enw
te hoeven gebruiken.'rb+'
- lees- en schrijfmodus in binair. Hetzelfde alsr+
behalve dat de gegevens binair zijn'wb'
- schrijfmodus in binair. Hetzelfde alsw
behalve dat de gegevens binair zijn.'w+'
- schrijf- en leesmodus. Precies hetzelfde alsr+
maar als het bestand niet bestaat, wordt er een nieuw gemaakt. Anders wordt het bestand overschreven.'wb+'
- schrijf- en leesmodus in binaire modus. Hetzelfde alsw+
maar de gegevens zijn binair.'ab'
- toevoegen in binaire modus. Vergelijkbaar meta
uitzondering dat de gegevens binair zijn.'a+'
- toevoegen en lezen. Vergelijkbaar metw+
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 alsa+
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, zalFileExistsError
verhogen als het bestand al bestaat -
'xb'
- open voor exclusieve creatie schrijfmodus in binair. Hetzelfde alsx
behalve dat de gegevens binair zijn. -
'x+'
- lees- en schrijfmodus. Vergelijkbaar metw+
omdat het een nieuw bestand maakt als het bestand niet bestaat. Anders wordtFileExistsError
verhoogd. -
'xb+'
- schrijf- en leesmodus. Precies hetzelfde alsx+
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:
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
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.
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
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')
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.
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.