Python Language
Pliki i foldery we / wy
Szukaj…
Wprowadzenie
Jeśli chodzi o przechowywanie, odczyt lub komunikację danych, praca z plikami systemu operacyjnego jest konieczna i łatwa w Pythonie. W przeciwieństwie do innych języków, w których wejście i wyjście pliku wymaga skomplikowanych obiektów do odczytu i zapisu, Python upraszcza proces, wymagając jedynie poleceń otwierania, odczytu / zapisu i zamykania pliku. W tym temacie wyjaśniono, jak Python może łączyć się z plikami w systemie operacyjnym.
Składnia
- file_object = open (nazwa pliku [, tryb_dostępu] [, buforowanie])
Parametry
Parametr | Detale |
---|---|
Nazwa pliku | ścieżka do pliku lub, jeśli plik znajduje się w katalogu roboczym, nazwa pliku |
tryb dostępu | wartość ciągu określająca sposób otwarcia pliku |
buforowanie | wartość całkowita używana do opcjonalnego buforowania linii |
Uwagi
Unikanie międzyplatformowego kodowania piekła
Korzystając z wbudowanej funkcji open()
Pythona, najlepszą praktyką jest zawsze przekazywanie argumentu encoding
, jeśli zamierzasz uruchamiać swój kod na różnych platformach. Powodem tego jest to, że domyślne kodowanie systemu różni się w zależności od platformy.
Choć linux
systemy rzeczywiście używać utf-8
jako domyślna, to niekoniecznie jest prawdą dla Mac i Windows.
Aby sprawdzić domyślne kodowanie systemu, spróbuj tego:
import sys
sys.getdefaultencoding()
z dowolnego interpretera Pythona.
Dlatego mądrze jest zawsze rozdzielić kodowanie, aby upewnić się, że łańcuchy, z którymi pracujesz, są zakodowane tak, jak myślisz, że są, co zapewnia zgodność między platformami.
with open('somefile.txt', 'r', encoding='UTF-8') as f:
for line in f:
print(line)
Tryby plików
Istnieją różne tryby, w których można otworzyć plik, określone przez parametr mode
. Obejmują one:
'r'
- tryb czytania. Domyślny. Pozwala tylko na odczyt pliku, a nie na jego modyfikację. Podczas korzystania z tego trybu plik musi istnieć.'w'
- tryb pisania. Utworzy nowy plik, jeśli nie istnieje, w przeciwnym razie usunie plik i pozwoli na zapisanie go.'a'
- tryb dołączania. Zapisuje dane na końcu pliku. Nie usuwa pliku, a plik musi istnieć w tym trybie.'rb'
- tryb odczytu w trybie binarnym. Jest to podobne dor
z tym wyjątkiem, że odczyt jest wymuszony w trybie binarnym. Jest to również wybór domyślny.'r+'
- jednocześnie tryb czytania i tryb pisania. Pozwala to na jednoczesne czytanie i zapisywanie plików bez konieczności używaniar
iw
.'rb+'
- tryb odczytu i zapisu w trybie binarnym. To samo cor+
tyle że dane są binarne'wb'
- tryb zapisu w trybie binarnym. To samo cow
z wyjątkiem danych w formacie binarnym.'w+'
- tryb pisania i czytania. Dokładnie tak samo jakr+
ale jeśli plik nie istnieje, tworzony jest nowy plik. W przeciwnym razie plik zostanie zastąpiony.'wb+'
- tryb pisania i czytania w trybie binarnym. To samo cow+
ale dane są binarne.'ab'
- dołączanie w trybie binarnym. Podobny do chyba że dane są w systemie binarnym.a
'a+'
- tryb dołączania i czytania. Podobne dow+
ponieważ utworzy nowy plik, jeśli plik nie istnieje. W przeciwnym razie wskaźnik pliku znajduje się na końcu pliku, jeśli istnieje.'ab+'
- dodawanie i czytanie w trybie binarnym. To samo, coa+
z tym wyjątkiem, że dane są binarne.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 + | za | a + | |
---|---|---|---|---|---|---|
Czytać | ✔ | ✔ | ✘ | ✔ | ✘ | ✔ |
pisać | ✘ | ✔ | ✔ | ✔ | ✔ | ✔ |
Tworzy plik | ✘ | ✘ | ✔ | ✔ | ✔ | ✔ |
Usuwa plik | ✘ | ✘ | ✔ | ✔ | ✘ | ✘ |
Pozycja początkowa | Początek | Początek | Początek | Początek | Koniec | Koniec |
Python 3 dodał nowy tryb exclusive creation
na exclusive creation
, aby nie przypadkowo obciąć lub zastąpić istniejący plik.
-
'x'
- otwarty do wyłącznego tworzenia, podniesieFileExistsError
jeśli plik już istnieje -
'xb'
- otwarty w trybie binarnym do pisania ekskluzywnych kreacji. To samo cox
tyle że dane są binarne. -
'x+'
- tryb czytania i pisania. Podobne dow+
ponieważ utworzy nowy plik, jeśli plik nie istnieje. W przeciwnym razie podniesieFileExistsError
. -
'xb+'
- tryb pisania i czytania. Dokładnie tak samo jakx+
ale dane są binarne
x | x + | |
---|---|---|
Czytać | ✘ | ✔ |
pisać | ✔ | ✔ |
Tworzy plik | ✔ | ✔ |
Usuwa plik | ✘ | ✘ |
Pozycja początkowa | Początek | Początek |
Pozwól, aby ktoś napisał otwarty kod pliku w bardziej pythonowy sposób:
try:
with open("fname", "r") as fout:
# Work with your open file
except FileExistsError:
# Your error handling goes here
W Python 2 zrobiłbyś coś takiego
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
Czytanie pliku wiersz po wierszu
Najprostszy sposób na iterację pliku wiersz po wierszu:
with open('myfile.txt', 'r') as fp:
for line in fp:
print(line)
readline()
pozwala na bardziej szczegółową kontrolę iteracji linia po linii. Poniższy przykład jest równoważny powyższemu:
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)
Używanie iteratora pętli for i readline () jest uważane za złą praktykę.
Częściej metoda readlines()
służy do przechowywania iterowalnej kolekcji linii pliku:
with open("myfile.txt", "r") as fp:
lines = fp.readlines()
for i in range(len(lines)):
print("Line " + str(i) + ": " + line)
Spowoduje to wydrukowanie następującego:
Wiersz 0: cześć
Wiersz 1: świat
Uzyskiwanie pełnej zawartości pliku
Preferowaną metodą pliku we / wy jest użycie słowa kluczowego with
. Zapewni to zamknięcie uchwytu pliku po zakończeniu odczytu lub zapisu.
with open('myfile.txt') as in_file:
content = in_file.read()
print(content)
lub, aby obsługiwać ręcznie zamykania pliku, można zrezygnować with
i po prostu zadzwonić close
siebie:
in_file = open('myfile.txt', 'r')
content = in_file.read()
print(content)
in_file.close()
Pamiętaj, że bez użycia instrukcji with
możesz przypadkowo pozostawić plik otwarty, na wypadek pojawienia się nieoczekiwanego wyjątku:
in_file = open('myfile.txt', 'r')
raise Exception("oops")
in_file.close() # This will never be called
Zapis do pliku
with open('myfile.txt', 'w') as f:
f.write("Line 1")
f.write("Line 2")
f.write("Line 3")
f.write("Line 4")
Jeśli otworzysz myfile.txt
, zobaczysz, że jego zawartość to:
Linia 1 Linia 2 Linia 3 Linia 4
Python nie dodaje automatycznie podziałów linii, musisz to zrobić ręcznie:
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")
Linia 1
Linia 2
Linia 3
Linia 4
Nie używaj os.linesep
jako terminatora linii podczas zapisywania plików otwartych w trybie tekstowym (domyślnie); zamiast tego użyj \n
.
Jeśli chcesz określić kodowanie, wystarczy dodać parametr encoding
do funkcji open
:
with open('my_file.txt', 'w', encoding='utf-8') as f:
f.write('utf-8 text')
Możliwe jest również użycie instrukcji print do zapisu do pliku. Mechanika jest inna w Pythonie 2 niż w Pythonie 3, ale koncepcja jest taka sama, ponieważ możesz pobrać dane wyjściowe, które trafiłyby na ekran i zamiast tego wysłać je do pliku.
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
W Python 2 zrobiłbyś coś takiego
outfile = open('fred.txt', 'w')
s = "I'm Not Dead Yet!"
print s # writes to stdout
print >> outfile, s # writes to outfile
W przeciwieństwie do funkcji zapisu funkcja drukowania automatycznie dodaje podział wiersza.
Kopiowanie zawartości jednego pliku do innego pliku
with open(input_file, 'r') as in_file, open(output_file, 'w') as out_file:
for line in in_file:
out_file.write(line)
- Za pomocą modułu
shutil
:
import shutil
shutil.copyfile(src, dst)
Sprawdź, czy istnieje plik lub ścieżka
Zastosuj styl kodowania EAFP i try
go otworzyć.
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
Pozwoli to również uniknąć warunków wyścigu, jeśli inny proces usunie plik między czekiem a jego użyciem. Ten stan wyścigu może się zdarzyć w następujących przypadkach:
Za pomocą modułu
os
:import os os.path.isfile('/path/to/some/file.txt')
Za pomocą
pathlib
:import pathlib path = pathlib.Path('/path/to/some/file.txt') if path.is_file(): ...
Aby sprawdzić, czy dana ścieżka istnieje, czy nie, możesz wykonać powyższą procedurę EAFP lub jawnie sprawdzić ścieżkę:
import os
path = "/home/myFiles/directory1"
if os.path.exists(path):
## Do stuff
Skopiuj drzewo katalogów
import shutil
source='//192.168.1.2/Daily Reports'
destination='D:\\Reports\\Today'
shutil.copytree(source, destination)
Katalog docelowy nie może już istnieć .
Iteruj pliki (rekurencyjnie)
Aby iterować wszystkie pliki, w tym w podkatalogach, użyj os.walk:
import os
for root, folders, files in os.walk(root_dir):
for filename in files:
print root, filename
katalog_główny może być „.” na początek z bieżącego katalogu lub inną ścieżkę na początek.
Jeśli chcesz również uzyskać informacje na temat pliku, możesz użyć bardziej wydajnej metody os.scandir w następujący sposób:
for entry in os.scandir(path):
if not entry.name.startswith('.') and entry.is_file():
print(entry.name)
Przeczytaj plik między zakresem linii
Załóżmy więc, że chcesz iterować tylko między określonymi wierszami pliku
Możesz do tego użyć narzędzi itertools
import itertools with open('myfile.txt', 'r') as f: for line in itertools.islice(f, 12, 30): # do something here
Spowoduje to odczytanie wierszy od 13 do 20, ponieważ w python indeksowanie rozpoczyna się od 0. Zatem wiersz 1 jest indeksowany jako 0
Jak również można przeczytać dodatkowe wiersze, używając tutaj słowa kluczowego next()
.
A gdy używasz obiektu pliku jako iterowalnego, nie używaj tutaj instrukcji readline()
, ponieważ dwie techniki przejścia pliku nie mogą być ze sobą mieszane
Losowy dostęp do plików za pomocą mmap
Użycie modułu mmap
pozwala użytkownikowi na losowy dostęp do lokalizacji w pliku poprzez mapowanie pliku do pamięci. Jest to alternatywa dla normalnych operacji na plikach.
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()
Zastępowanie tekstu w pliku
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='')
Sprawdzanie, czy plik jest pusty
>>> import os
>>> os.stat(path_to_file).st_size == 0
lub
>>> import os
>>> os.path.getsize(path_to_file) > 0
Jednak oba zgłoszą wyjątek, jeśli plik nie istnieje. Aby uniknąć konieczności wychwycenia takiego błędu, wykonaj następujące czynności:
import os
def is_empty_file(fpath):
return os.path.isfile(fpath) and os.path.getsize(fpath) > 0
co zwróci wartość bool
.