Плутати в режимі файлу python “w +”


203

З доку ,

Режими 'r +', 'w +' і 'a +' відкривають файл для оновлення (зауважте, що 'w +' обрізає файл). Додайте «b» до режиму, щоб відкрити файл у двійковому режимі, у системах, які розрізняють двійкові та текстові файли; у системах, які не мають цього розрізнення, додавання значення "b" не впливає.

і тут

w +: відкриває файл для запису та читання. Перезаписує наявний файл, якщо файл існує. Якщо файл не існує, створюється новий файл для читання та запису.

Але, як читати файл, відкритий за допомогою w+?


27
Цю діаграму я вважаю досить корисною.
Рітвік

Відповіді:


133

Скажімо, ви відкриваєте файл із withзаявою, якою має бути. Тоді ви зробите щось подібне, щоб прочитати з вашого файлу:

with open('somefile.txt', 'w+') as f:
    # Note that f has now been truncated to 0 bytes, so you'll only
    # be able to read data that you write after this point
    f.write('somedata\n')
    f.seek(0)  # Important: return to the top of the file before reading, otherwise you'll just read an empty string
    data = f.read() # Returns 'somedata\n'

Зауважте f.seek(0)- якщо ви це забудете, f.read()виклик буде намагатися прочитати з кінця файлу і поверне порожню рядок.


1
що означає "обрізання на 0 байт"?
Насіф Імтіаз Охі

22
@NasifImtiazOhi - Документи Python кажуть, що w+"замінить існуючий файл, якщо файл існує". Отож, як тільки ви відкриєте файл із w+, він тепер порожній файл: він містить 0 байт. Якщо він раніше містив дані, ці дані були усічені - відрізані та викинуті - а тепер розмір файлу становить 0 байт, тому ви не можете прочитати жодну з даних, що існували до того, як ви відкрили файл w+. Якщо ви насправді хотіли прочитати попередні дані та додати до них, вам слід використовувати r+замість w+.
rmunn

як додати нові дані зверху?
Бека Бухрадзе

1
@BeqaBukhradze - Якщо у вас є питання, натисніть кнопку "Задати питання", де його побачать сотні людей. Не просто натискайте кнопку "Додати коментар", де її побачать лише один або два людини.
rmunn

434

Ось перелік різних режимів відкриття файлу:

  • r

    Відкриває файл лише для читання. Вказівник на файл розміщується на початку файлу. Це режим за замовчуванням.

  • rb

    Відкриває файл для читання лише у двійковому форматі. Вказівник на файл розміщується на початку файлу. Це режим за замовчуванням.

  • r +

    Відкриває файл як для читання, так і для запису. Покажчик файлу буде на початку файлу.

  • rb +

    Відкриває файл для читання та запису у двійковому форматі. Покажчик файлу буде на початку файлу.

  • ш

    Відкриває файл лише для запису. Перезаписує файл, якщо файл існує. Якщо файл не існує, створюється новий файл для запису.

  • wb

    Відкриває файл для запису лише у двійковому форматі. Перезаписує файл, якщо файл існує. Якщо файл не існує, створюється новий файл для запису.

  • w +

    Відкриває файл як для запису, так і для читання. Перезаписує наявний файл, якщо файл існує. Якщо файл не існує, створюється новий файл для читання та запису.

  • wb +

    Відкриває файл для запису та читання у двійковому форматі. Перезаписує наявний файл, якщо файл існує. Якщо файл не існує, створюється новий файл для читання та запису.

  • а

    Відкриває файл для додавання. Указівник на файл знаходиться в кінці файлу, якщо файл існує. Тобто файл знаходиться в режимі додавання. Якщо файл не існує, він створює новий файл для запису.

  • аб

    Відкриває файл для додавання у двійковому форматі. Указівник на файл знаходиться в кінці файлу, якщо файл існує. Тобто файл знаходиться в режимі додавання. Якщо файл не існує, він створює новий файл для запису.

  • a +

    Відкриває файл для додавання та читання. Указівник на файл знаходиться в кінці файлу, якщо файл існує. Файл відкривається в режимі додавання. Якщо файл не існує, він створює новий файл для читання та запису.

  • ab +

    Відкриває файл для додавання та читання у двійковому форматі. Указівник на файл знаходиться в кінці файлу, якщо файл існує. Файл відкривається в режимі додавання. Якщо файл не існує, він створює новий файл для читання та запису.


22
@Humdinger: ні, w+створює новий файл або обрізає існуючий файл, потім відкриває його для читання та запису; r+відкриває існуючий файл без обрізки для читання та запису. Дуже різні.
abarnert

1
Також, як і у відповіді @ AlokAgarwal, це стверджує, що це вичерпний перелік режимів, але це не так.
abarnert

1
Було б досить нерозумно дати вичерпний список режимів, оскільки вони більше нагадують функцію з кількома параметрами. r, wабо aє ексклюзивними, але bїх можна додати до будь-якого з них, як можна +, або U... Це комбінаторний вибух.
rmunn

4
rbне є типовим режимом, цитата: The most commonly-used values of mode are 'r' for reading, 'w' for writing (truncating the file if it already exists), and 'a' for appending (which on some Unix systems means that all writes append to the end of the file regardless of the current seek position). If mode is omitted, it defaults to 'r' docs.python.org/2/library/functions.html#open
iggy

1
Можливо, ми можемо додати режим "x", він же "ексклюзивне створення": це створює файл (для запису), якщо його не існує, і підвищує FileExistsError, якщо його немає.
Ларикс Декідуа

158

Всі режими файлів у Python

  • r для читання
  • r+ відкривається для читання та запису (не вдається врізати файл)
  • w для написання
  • w+ для запису та читання (може усікати файл)
  • rbдля читання двійкового файлу. Вказівник на файл розміщується на початку файлу.
  • rb+ читання або запис двійкового файлу
  • wb+ запис двійкового файлу
  • a+ відкривається для додавання
  • ab+Відкриває файл для додавання та читання у двійковій формі. Указівник на файл знаходиться в кінці файлу, якщо файл існує. Файл відкривається в режимі додавання.
  • x відкрито для ексклюзивного створення, якщо програма вже існує (Python 3)

5
Це не всі режими. Це нехтує, наприклад, rbі wb, не кажучи вже про Uрежими в 2.x та tрежимі в 3.x (які можуть поєднуватися з усім, крім b).
abarnert

1
Різниця між r + і w + полягає в тому, що w + скорочує файл при його відкритті. Але ви можете обрізати його вручну в обох режимах.
Мартін

1
Ця відповідь не відповідає тій, яку дає @ 200 ОК, наприклад, чи wb+читається також з файлу?
Celeritas

@Celeritas Wb вказує, що файл відкритий для запису у двійковому режимі. У системах Unix (Linux, Mac OS X тощо) двійковий режим нічого не робить - вони обробляють текстові файли так само, як і будь-які інші файли. Однак у Windows текстові файли записуються із дещо зміненими закінченнями рядків. Це спричиняє серйозну проблему при роботі з фактичними бінарними файлами, такими як EXE або jpg. Тому, відкриваючи файли, які не повинні бути текстовими, навіть в Unix, ви повинні використовувати wb або rb. Використовуйте звичайний w або r лише для текстових файлів.
Алок Агарвал

У Python 3 також є відкритий режим 'x': відкритий для ексклюзивного створення, не вдається, якщо файл вже існує. Дивіться функцію відкриття в док.
Лоран ЛАПОРТЕ

9

r для читання

w для запису

r+ для читання / запису без видалення вихідного вмісту, якщо файл існує, інакше підняти виняток

w+ для видалення вихідного вмісту потім прочитайте / запишіть, якщо файл існує, інакше створіть файл

Наприклад,

>>> with open("file1.txt", "w") as f:
...   f.write("ab\n")
... 
>>> with open("file1.txt", "w+") as f:
...   f.write("c")
... 

$ cat file1.txt 
c$
>>> with open("file2.txt", "r+") as f:
...   f.write("ab\n")
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: 'file2.txt'
>>> with open("file2.txt", "w") as f:
...   f.write("ab\n")
... 
>>> with open("file2.txt", "r+") as f:
...   f.write("c")
... 

$ cat file2.txt 
cb
$

2

Файл урізаний, тому ви можете дзвонити read()(винятків не піднімається, на відміну від відкритого за допомогою "w"), але ви отримаєте порожню рядок.


2

Я підозрюю, що існує два способи вирішити те, що я думаю, що ти намагаєшся досягти.

1) що очевидно: відкрийте файл лише для читання, прочитайте його в пам'яті, потім відкрийте файл з t, а потім запишіть зміни.

2) використовувати підпрограми обробки файлів низького рівня:

# Open file in RW , create if it doesn't exist. *Don't* pass O_TRUNC
 fd = os.open(filename, os.O_RDWR | os.O_CREAT)

Сподіваюся, це допомагає ..


Тоді для чого r+
SmartManoj

1

Власне, у всіх інших відповідях про r+режим щось не так .

test.in вміст файлу:

hello1
ok2
byebye3

І сценарій py:

with open("test.in", 'r+')as f:
    f.readline()
    f.write("addition")

Виконайте це, і test.inзміст вмісту буде змінено на:

hello1
ok2
byebye3
addition

Однак коли ми модифікуємо сценарій на:

with open("test.in", 'r+')as f:
    f.write("addition")

відповідь test.inтакож:

additionk2
byebye3

Отже, r+режим дозволить нам охоплювати вміст з самого початку, якщо ми не зробили операцію читання. І якщо ми зробимо деяку операцію з читання, f.write()просто додамо до файлу.

До речі, якщо ми f.seek(0,0)раніше f.write(write_content), write_content буде покривати їх з позиції (0,0).


0

Як згадує h4z3 , Для практичного використання іноді ваші дані занадто великі, щоб безпосередньо все завантажувати, або у вас є генератор або вхідні дані в реальному часі, ви можете використовувати w + для зберігання у файлі та читання пізніше.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.