Różnica między trybami a, a +, w, w + i r + we wbudowanej funkcji otwartej?

608

W pytona wbudowanym otwartym funkcją, jaka jest dokładna różnica między trybami w, a, w+, a+, i r+?

W szczególności dokumentacja implikuje, że wszystkie one pozwolą na zapis do pliku i mówi, że otwiera pliki do „dołączania”, „pisania” i „aktualizowania”, ale nie określa, co oznaczają te terminy.

Lecieć jak po sznurku
źródło
11
Podany link dokładnie określa wartości. Której części podanego linku nie widziałeś ani nie rozumiałeś? Czy możesz wyjaśnić swoje pytanie, aby wyjaśnić, czego nie rozumiesz na temat linku?
S.Lott,
@ChrisB. - Zgłosiłem to jako błąd na bugs.python.org/issue19627
Bulwersator
2
czy nie ma prostego i pojedynczego dokumentu wyjaśniającego, co oznacza znak +?
Charlie Parker

Odpowiedzi:

740

Tryby otwarcia są dokładnie takie same, jak dla funkcji standardowej biblioteki C fopen().

BSD fopenpodręcznika definiuje je następująco:

 The argument mode points to a string beginning with one of the following
 sequences (Additional characters may follow these sequences.):

 ``r''   Open text file for reading.  The stream is positioned at the
         beginning of the file.

 ``r+''  Open for reading and writing.  The stream is positioned at the
         beginning of the file.

 ``w''   Truncate file to zero length or create text file for writing.
         The stream is positioned at the beginning of the file.

 ``w+''  Open for reading and writing.  The file is created if it does not
         exist, otherwise it is truncated.  The stream is positioned at
         the beginning of the file.

 ``a''   Open for writing.  The file is created if it does not exist.  The
         stream is positioned at the end of the file.  Subsequent writes
         to the file will always end up at the then current end of file,
         irrespective of any intervening fseek(3) or similar.

 ``a+''  Open for reading and writing.  The file is created if it does not
         exist.  The stream is positioned at the end of the file.  Subse-
         quent writes to the file will always end up at the then current
         end of file, irrespective of any intervening fseek(3) or similar.
drAlberT
źródło
3
Myślę, że masz na myśli połączenie fopen ze standardowej biblioteki C (które nie jest wywołaniem systemowym)
Eli Courtwright
14
UWAGA: Python v3 dodaje wiele dodatkowych trybów. link do dokumentacji
Alex
5
Zauważyłem, że wi w+oboje mogą to zrobićThe file is created if it does not exist
Wei Yang
4
W systemie Windows bdołączany do trybu otwiera plik w trybie binarnym, więc istnieje również tryby takie jak rb, wbi r+b. Python w systemie Windows rozróżnia pliki tekstowe i binarne; znaki końca wiersza w plikach tekstowych są automatycznie nieznacznie zmieniane podczas odczytu lub zapisu danych.
6
czy mam rację twierdząc, że +nie robi czegoś spójnego niezależnie, jeśli tak jest a, wczy r? A może nie widzę wzoru? Jaki jest wzór?
Charlie Parker
508

Zauważyłem, że od czasu do czasu muszę ponownie otwierać Google, aby stworzyć mentalny obraz podstawowych różnic między trybami. Pomyślałem więc, że następnym razem będzie szybciej czytać diagram. Może ktoś inny również uzna to za pomocne.

Andrzej Pronobis
źródło
3
aOpis jest źle . Zapisy są zawsze umieszczane na końcu.
Antti Haapala,
10
@A wierzę, że @Antti odnosi się do nieruchomości, Subsequent writes to the file will always end up at the then current end of file, irrespective of any intervening fseek(3) or similarktóra jest nieco silniejsza niż zwykłe stwierdzenie, że początkowa pozycja to koniec.
jcai
8
@CharlieParker Istnieją dwie operacje na plikach (odczyt, zapis). Tryb r jest przede wszystkim do czytania, tryby w , a są głównie do pisania. A znak plus umożliwia drugą operację dla danego trybu (mówiąc wprost).
Jeyekomon,
22
Dla potomności: obcinanie oznacza nadpisywanie od początku.
Minh Tran
4
@Jeyekomon Twoje streszczenie w komentarzu tutaj jest prawdopodobnie NAJBARDZIEJ najbardziej pomocną rzeczą, jaką przeczytałem, próbując obejść te tryby w sposób, który teraz pamiętam! Schemat blokowy w tej odpowiedzi jest piękny, a tabela w poniższej odpowiedzi jest świetna, ale jeśli te odpowiedzi (i inne gdzie indziej) zaczęły się od tego prostego punktu i działały stamtąd, pomogłoby to zapewnić znacznie lepsze ramy mentalne do zawieszenia szczegółów na. Więc dziękuję. (Zdaję sobie sprawę, że to może być granica spamu, ale czułem, że twój komentarz zasługuje na potwierdzenie)
Tim
206

Te same informacje, tylko w formie tabeli

                  | r   r+   w   w+   a   a+
------------------|--------------------------
read              | +   +        +        +
write             |     +    +   +    +   +
write after seek  |     +    +   +
create            |          +   +    +   +
truncate          |          +   +
position at start | +   +    +   +
position at end   |                   +   +

gdzie są znaczenia: (aby uniknąć błędnej interpretacji)

  • odczyt - odczyt z pliku jest dozwolony
  • write - zapis do pliku jest dozwolony

  • Utwórz - plik jest tworzony, jeśli jeszcze nie istnieje

  • trunctate - podczas otwierania pliku jest pusty (cała zawartość pliku jest kasowana)

  • pozycja na początku - po otwarciu pliku pozycja początkowa jest ustawiana na początek pliku

  • pozycja na końcu - po otwarciu pliku pozycja początkowa jest ustawiana na końcu pliku

Uwaga: ai a+zawsze dołączaj na końcu pliku - ignoruje wszelkie seekruchy.
BTW. ciekawe zachowanie przynajmniej na moim win7 / python2.7, dla nowego pliku otwartego w a+trybie:
write('aa'); seek(0, 0); read(1); write('b')- drugi writejest ignorowany
write('aa'); seek(0, 0); read(2); write('b')- drugi writepodnosiIOError

pracownik przemysłu 3595112
źródło
10
Dlaczego nie ma opcji „Utwórz plik, jeśli nie istnieje. Jeśli istnieje, ustaw na początku, włącz odczyt i zapis”? Jest to dla mnie najbardziej oczywisty przypadek użycia: przechowuję dane w pliku. Jeśli pliku nie ma, utwórz go zamiast popełniania błędów. Jeśli w pliku znajdują się dane, które chcę przeczytać wszystko od góry, zaktualizuj niektóre rzeczy, a następnie całkowicie ponownie napisz plik od 0 na następny czas, kiedy go załaduję. Używam tego, open(file,'a'); close(); open(file,'r+')aby to osiągnąć.
pinhead
2
Co w tym kontekście oznacza „obcinanie”?
Charlie Parker
3
@CharlieParker Oznacza to, że cała zawartość pliku jest usuwana (plik jest pusty)
industryworker3595112
1
Możesz dodać notatkę, że za pomocą ai a+zapisy zawsze będą się pojawiać na końcu pliku, niezależnie od tego, czy ręcznie przesuwasz wskaźnik za pomocą seek().
balu,
1
Co z aktualizacją tabeli, aby zawierała „x” dla Pythona 3?
Nikos Alexandris,
39

Opcje są takie same jak dla funkcji fopen w standardowej bibliotece C:

w obcina plik, zastępując wszystko, co już tam było

a dołącza się do pliku, dodając do wszystkiego, co już tam było

w+ otwiera się do odczytu i zapisu, obcinając plik, ale także umożliwiając odczytanie tego, co zostało zapisane do pliku

a+ otwiera się do dołączania i czytania, umożliwiając zarówno dołączenie do pliku, jak i odczytanie jego zawartości

Eli Courtwright
źródło
2
Co w tym kontekście oznacza „obcinanie”? Czy oznacza to usunięcie starych danych, jeśli miały jakieś? A może coś bardziej konkretnego?
Charlie Parker
3
@CharlieParker: Poprawnie - oznacza to, że wszystkie dane w istniejącym pliku zostaną usunięte i zaczniemy pisać od początku pustego pliku.
Eli Courtwright
9

Myślę, że należy to wziąć pod uwagę przy realizacji na wielu platformach, tj. Jako CYA. :)

W systemie Windows „b” dołączony do trybu otwiera plik w trybie binarnym, więc istnieją również tryby takie jak „rb”, „wb” i „r + b”. Python w systemie Windows rozróżnia pliki tekstowe i binarne; znaki końca wiersza w plikach tekstowych są automatycznie nieznacznie zmieniane podczas odczytu lub zapisu danych. Ta zakulisowa modyfikacja danych pliku jest odpowiednia dla plików tekstowych ASCII, ale spowoduje uszkodzenie takich danych binarnych w plikach JPEG lub EXE. Podczas odczytu i zapisu takich plików należy bardzo uważać na tryb binarny. W systemie Unix dodanie „b” do trybu nie boli, więc możesz używać go niezależnie od platformy dla wszystkich plików binarnych.

Jest to bezpośrednio notowane od Python Software Foundation 2.7.x .

Goran B.
źródło
9

Zastanawiam się nad tym, próbując dowiedzieć się, dlaczego miałbyś używać trybu „w +” kontra „w”. W końcu właśnie przeprowadziłem testy. Nie widzę większego sensu dla trybu „w +”, ponieważ w obu przypadkach plik jest na początku obcięty. Jednak dzięki „w +” możesz czytać po napisaniu, szukając wstecz. Jeśli spróbujesz czytać z „w”, spowoduje to IOError. Czytanie bez korzystania z trybu wyszukiwania w trybie „w +” nic nie da, ponieważ wskaźnik pliku będzie po tym, co napisałeś.

Wyrmwood
źródło