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 do r 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żywania r i w .

  • 'rb+' - tryb odczytu i zapisu w trybie binarnym. To samo co r+ tyle że dane są binarne

  • 'wb' - tryb zapisu w trybie binarnym. To samo co w z wyjątkiem danych w formacie binarnym.

  • 'w+' - tryb pisania i czytania. Dokładnie tak samo jak r+ 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 co w+ 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 do w+ 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, co a+ 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, podniesie FileExistsError jeśli plik już istnieje
  • 'xb' - otwarty w trybie binarnym do pisania ekskluzywnych kreacji. To samo co x tyle że dane są binarne.
  • 'x+' - tryb czytania i pisania. Podobne do w+ ponieważ utworzy nowy plik, jeśli plik nie istnieje. W przeciwnym razie podniesie FileExistsError .
  • 'xb+' - tryb pisania i czytania. Dokładnie tak samo jak x+ 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:

Python 3.x 3.3
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

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

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.

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

W Python 2 zrobiłbyś coś takiego

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

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')
    
Python 3.x 3.4
  • 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.

Python 3.x 3.5

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 .



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow