Python Language
File e cartelle I / O
Ricerca…
introduzione
Quando si tratta di memorizzare, leggere o comunicare dati, lavorare con i file di un sistema operativo è sia necessario che facile con Python. A differenza di altri linguaggi in cui l'input e l'output dei file richiedono oggetti di lettura e scrittura complessi, Python semplifica il processo richiedendo solo i comandi per aprire, leggere / scrivere e chiudere il file. Questo argomento spiega come Python può interfacciarsi con i file sul sistema operativo.
Sintassi
- file_object = open (filename [, access_mode] [, buffering])
Parametri
Parametro | Dettagli |
---|---|
nome del file | il percorso del tuo file o, se il file è nella directory di lavoro, il nome del file |
access_mode | un valore stringa che determina come viene aperto il file |
il buffering | un valore intero utilizzato per il buffering di riga opzionale |
Osservazioni
Evitare l'Encoding Hell multipiattaforma
Quando si utilizza open()
Python, è consigliabile passare sempre l'argomento di encoding
, se si intende eseguire il codice su più piattaforme. Il motivo di ciò è che la codifica predefinita di un sistema differisce da piattaforma a piattaforma.
Mentre i sistemi linux
usano effettivamente utf-8
come default, questo non è necessariamente vero per MAC e Windows.
Per verificare la codifica predefinita di un sistema, prova questo:
import sys
sys.getdefaultencoding()
da qualsiasi interprete python.
Pertanto, è consigliabile separare sempre una codifica, per assicurarsi che le stringhe con cui si sta lavorando siano codificate come ciò che si pensa di essere, garantendo la compatibilità tra piattaforme diverse.
with open('somefile.txt', 'r', encoding='UTF-8') as f:
for line in f:
print(line)
Modalità file
Esistono diverse modalità con cui è possibile aprire un file, specificato dal parametro mode
. Questi includono:
'r'
- modalità di lettura. Il predefinito. Ti permette solo di leggere il file, non di modificarlo. Quando si utilizza questa modalità, il file deve esistere.'w'
- modalità di scrittura. Creerà un nuovo file se non esiste, altrimenti cancellerà il file e ti consentirà di scrivere su di esso.'a'
- modalità append. Scriverà i dati alla fine del file. Non cancella il file e il file deve esistere per questa modalità.'rb'
- modalità di lettura in binario. Questo è simile ar
tranne che la lettura è forzata in modalità binaria. Anche questa è una scelta predefinita.'r+'
- modalità di lettura più modalità di scrittura allo stesso tempo. Ciò consente di leggere e scrivere in file contemporaneamente senza dover utilizzarer
ew
.'rb+'
- modalità di lettura e scrittura in binario. Lo stesso dir+
tranne che i dati sono in binario'wb'
- modalità di scrittura in binario. Lo stesso diw
eccetto che i dati sono in binario.'w+'
- modalità di scrittura e lettura. Esattamente comer+
ma se il file non esiste, ne viene creato uno nuovo. Altrimenti, il file viene sovrascritto.'wb+'
- modalità di scrittura e lettura in modalità binaria. Lo stesso diw+
ma i dati sono in binario.'ab'
- l'aggiunta in modalità binaria. Simile ada
tranne che i dati sono in binario.'a+'
- modalità di aggiunta e lettura. Simile aw+
in quanto creerà un nuovo file se il file non esiste. Altrimenti, il puntatore del file si trova alla fine del file, se esiste.'ab+'
- modalità di aggiunta e lettura in binario. Ugualea+
tranne che i dati sono in binario.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 + | un | un + | |
---|---|---|---|---|---|---|
Leggere | ✔ | ✔ | ✘ | ✔ | ✘ | ✔ |
Scrivi | ✘ | ✔ | ✔ | ✔ | ✔ | ✔ |
Crea un file | ✘ | ✘ | ✔ | ✔ | ✔ | ✔ |
Cancella il file | ✘ | ✘ | ✔ | ✔ | ✘ | ✘ |
Posizione iniziale | Inizio | Inizio | Inizio | Inizio | Fine | Fine |
Python 3 ha aggiunto una nuova modalità per la exclusive creation
modo da non troncare o sovrascrivere accidentalmente e file esistenti.
-
'x'
: aperto per la creazione esclusiva, genereràFileExistsError
se il file esiste già -
'xb'
: aperto per la modalità di scrittura di creazione esclusiva in binario. Lo stesso dix
eccetto che i dati sono in binario. -
'x+'
- modalità di lettura e scrittura. Simile aw+
in quanto creerà un nuovo file se il file non esiste. Altrimenti, genereràFileExistsError
. -
'xb+'
- modalità di scrittura e lettura. Esattamente comex+
ma i dati sono binari
X | x + | |
---|---|---|
Leggere | ✘ | ✔ |
Scrivi | ✔ | ✔ |
Crea un file | ✔ | ✔ |
Cancella il file | ✘ | ✘ |
Posizione iniziale | Inizio | Inizio |
Consentire a uno di scrivere il codice aperto del file in modo più pignolo:
try:
with open("fname", "r") as fout:
# Work with your open file
except FileExistsError:
# Your error handling goes here
In Python 2 avresti fatto qualcosa di simile
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
Leggere un file riga per riga
Il modo più semplice per scorrere su un file riga per riga:
with open('myfile.txt', 'r') as fp:
for line in fp:
print(line)
readline()
consente un controllo più granulare su iterazione linea per riga. L'esempio sotto è equivalente a quello sopra:
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)
Usare l'iteratore loop for e readline () insieme è considerato una cattiva pratica.
Più comunemente, il metodo readlines()
viene utilizzato per memorizzare una raccolta iterabile delle righe del file:
with open("myfile.txt", "r") as fp:
lines = fp.readlines()
for i in range(len(lines)):
print("Line " + str(i) + ": " + line)
Questo dovrebbe stampare quanto segue:
Linea 0: ciao
Linea 1: mondo
Ottenere l'intero contenuto di un file
Il metodo preferito di file i / o è quello di utilizzare la parola chiave with
. Ciò garantirà che l'handle del file venga chiuso una volta completata la lettura o la scrittura.
with open('myfile.txt') as in_file:
content = in_file.read()
print(content)
o, per gestire la chiusura del file manualmente, si può rinunciare with
e semplicemente chiamare close
te stesso:
in_file = open('myfile.txt', 'r')
content = in_file.read()
print(content)
in_file.close()
Tieni presente che senza utilizzare un'istruzione with
, potresti accidentalmente mantenere il file aperto nel caso si verificasse un'eccezione imprevista in questo modo:
in_file = open('myfile.txt', 'r')
raise Exception("oops")
in_file.close() # This will never be called
Scrivere su un file
with open('myfile.txt', 'w') as f:
f.write("Line 1")
f.write("Line 2")
f.write("Line 3")
f.write("Line 4")
Se apri myfile.txt
, vedrai che il suo contenuto è:
Linea 1 Linea 2 Linea 3 Linea 4
Python non aggiunge automaticamente interruzioni di riga, è necessario farlo manualmente:
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")
Linea 1
Linea 2
Linea 3
Linea 4
Non utilizzare os.linesep
come terminatore di riga durante la scrittura di file aperti in modalità testo (impostazione predefinita); usa invece \n
.
Se si desidera specificare una codifica, è sufficiente aggiungere il parametro di encoding
alla funzione di open
:
with open('my_file.txt', 'w', encoding='utf-8') as f:
f.write('utf-8 text')
È anche possibile utilizzare l'istruzione print per scrivere su un file. Le meccaniche sono diverse in Python 2 vs Python 3, ma il concetto è lo stesso in quanto puoi prendere l'output che sarebbe andato sullo schermo e invece inviarlo a un file.
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 avresti fatto qualcosa di simile
outfile = open('fred.txt', 'w')
s = "I'm Not Dead Yet!"
print s # writes to stdout
print >> outfile, s # writes to outfile
A differenza dell'utilizzo della funzione di scrittura, la funzione di stampa aggiunge automaticamente interruzioni di riga.
Copia del contenuto di un file in un altro file
with open(input_file, 'r') as in_file, open(output_file, 'w') as out_file:
for line in in_file:
out_file.write(line)
- Usando il modulo
shutil
:
import shutil
shutil.copyfile(src, dst)
Controlla se esiste un file o percorso
Impiega lo stile di codifica EAFP e try
ad aprirlo.
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
Ciò eviterà anche le condizioni di gara se un altro processo ha cancellato il file tra il controllo e quando viene utilizzato. Questa condizione di competizione potrebbe verificarsi nei seguenti casi:
Usando il modulo
os
:import os os.path.isfile('/path/to/some/file.txt')
Utilizzando
pathlib
:import pathlib path = pathlib.Path('/path/to/some/file.txt') if path.is_file(): ...
Per verificare se esiste un determinato percorso o meno, è possibile seguire la procedura EAFP sopra indicata oppure controllare esplicitamente il percorso:
import os
path = "/home/myFiles/directory1"
if os.path.exists(path):
## Do stuff
Copia un albero di directory
import shutil
source='//192.168.1.2/Daily Reports'
destination='D:\\Reports\\Today'
shutil.copytree(source, destination)
La directory di destinazione non deve esistere già.
Iterare i file (in modo ricorsivo)
Per ripetere tutti i file, incluso nelle sottodirectory, utilizzare os.walk:
import os
for root, folders, files in os.walk(root_dir):
for filename in files:
print root, filename
root_dir può essere "." per iniziare dalla directory corrente o da qualsiasi altro percorso da cui partire.
Se desideri anche ottenere informazioni sul file, puoi utilizzare il metodo più efficiente os.scandir in questo modo:
for entry in os.scandir(path):
if not entry.name.startswith('.') and entry.is_file():
print(entry.name)
Leggi un file tra un intervallo di linee
Quindi supponiamo di voler ripetere solo tra alcune linee specifiche di un file
Puoi fare uso di itertools
per quello
import itertools with open('myfile.txt', 'r') as f: for line in itertools.islice(f, 12, 30): # do something here
Questo leggerà le righe da 13 a 20 come nell'indicizzazione python inizia da 0. Quindi la riga numero 1 è indicizzata come 0
Come può anche leggere alcune righe aggiuntive facendo uso della parola chiave next()
qui.
E quando usi l'oggetto file come un iterabile, per favore non usare l'istruzione readline()
qui perché le due tecniche di attraversamento di un file non devono essere mescolate insieme
Accesso casuale ai file tramite mmap
L'uso del modulo mmap
consente all'utente di accedere in modo casuale a posizioni in un file mappando il file in memoria. Questa è un'alternativa all'uso delle normali operazioni sui file.
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()
Sostituzione del testo in un file
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='')
Verifica se un file è vuoto
>>> import os
>>> os.stat(path_to_file).st_size == 0
o
>>> import os
>>> os.path.getsize(path_to_file) > 0
Tuttavia, entrambi genereranno un'eccezione se il file non esiste. Per evitare di dover rilevare un errore simile, procedere come segue:
import os
def is_empty_file(fpath):
return os.path.isfile(fpath) and os.path.getsize(fpath) > 0
che restituirà un valore bool
.