Питон запись в файл: Файлы. Работа с файлами. | Python 3 для начинающих и чайников
Содержание
Файлы. Работа с файлами. | Python 3 для начинающих и чайников
В данной статье мы рассмотрим встроенные средства python для работы с файлами: открытие / закрытие, чтение и запись.
Итак, начнем. Прежде, чем работать с файлом, его надо открыть. С этим замечательно справится встроенная функция open:
f = open('text.txt', 'r')
У функции open много параметров, они указаны в статье «Встроенные функции», нам пока важны 3 аргумента: первый, это имя файла. Путь к файлу может быть относительным или абсолютным. Второй аргумент, это режим, в котором мы будем открывать файл.
Режим | Обозначение |
‘r’ | открытие на чтение (является значением по умолчанию). |
‘w’ | открытие на запись, содержимое файла удаляется, если файла не существует, создается новый. |
‘x’ | открытие на запись, если файла не существует, иначе исключение. |
‘a’ | открытие на дозапись, информация добавляется в конец файла. |
‘b’ | открытие в двоичном режиме. |
‘t’ | открытие в текстовом режиме (является значением по умолчанию). |
‘+’ | открытие на чтение и запись |
Режимы могут быть объединены, то есть, к примеру, ‘rb’ — чтение в двоичном режиме. По умолчанию режим равен ‘rt’.
И последний аргумент, encoding, нужен только в текстовом режиме чтения файла. Этот аргумент задает кодировку.
Чтение из файла
Открыли мы файл, а теперь мы хотим прочитать из него информацию. Для этого есть несколько способов, но большого интереса заслуживают лишь два из них.
Первый — метод read, читающий весь файл целиком, если был вызван без аргументов, и n символов, если был вызван с аргументом (целым числом n).
>>> f = open('text.txt') >>> f.read(1) 'H' >>> f.read() 'ello world!\nThe end.\n\n'
Ещё один способ сделать это — прочитать файл построчно, воспользовавшись циклом for:
>>> f = open('text.txt') >>> for line in f: ... line ... 'Hello world!\n' '\n' 'The end.\n' '\n'
Запись в файл
Теперь рассмотрим запись в файл. Попробуем записать в файл вот такой вот список:
>>> l = [str(i)+str(i-1) for i in range(20)] >>> l ['0-1', '10', '21', '32', '43', '54', '65', '76', '87', '98', '109', '1110', '1211', '1312', '1413', '1514', '1615', '1716', '1817', '1918']
Откроем файл на запись:
>>> f = open('text.txt', 'w')
Запись в файл осуществляется с помощью метода write:
>>> for index in l: ... f.write(index + '\n') ... 4 3 3 3 3
Для тех, кто не понял, что это за цифры, поясню: метод write возвращает число записанных символов.
После окончания работы с файлом его обязательно нужно закрыть с помощью метода close:
>>> f.close()
Теперь попробуем воссоздать этот список из получившегося файла. Откроем файл на чтение (надеюсь, вы поняли, как это сделать?), и прочитаем строки.
>>> f = open('text.txt', 'r') >>> l = [line.strip() for line in f] >>> l ['0-1', '10', '21', '32', '43', '54', '65', '76', '87', '98', '109', '1110', '1211', '1312', '1413', '1514', '1615', '1716', '1817', '1918'] >>> f.close()
Мы получили тот же список, что и был. В более сложных случаях (словарях, вложенных кортежей и т. д.) алгоритм записи придумать сложнее. Но это и не нужно. В python уже давно придумали средства, такие как pickle или json, позволяющие сохранять в файле сложные структуры.
Запись в файл Python. Перезапись файла Python
Высокоуровневый язык Python 3 имеет множество полезных средств, позволяющих взаимодействовать с текстовыми файлами. Вы можете как создавать документы для хранения информации, так и выполнять чтение, запись и удаление данных. Сегодня поговорим о создании и записи файлов.
Создание файла, его открытие и закрытие
Работа с текстовым файлом в Python начинается с момента вызова функции open. Она принимает в качестве атрибутов путь к объекту на ПК и режим обработки. Вы можете указать абсолютный путь (это адрес размещения на жёстком диске) или относительный (речь идёт о координатах относительно папки проекта).
Что касается режима обработки файла, то при его выборе учитывайте его назначение («r» — для чтения, «w» — для записи). Таблица ниже позволит вам ознакомиться с режимами доступа к файлу в Python:
А вот пример простейшего взаимодействия с текстовым документом:
file = open("otus.txt", "w") file.write("hello world") file.close()Здесь функция open принимает относительный путь, открывая его для записи. При этом, если в папке файл otus.txt будет отсутствовать, метод open создает его автоматически, после чего откроет для него нужный режим обработки.
Метод close закрывает файл, а это необходимо сделать, выполнив нужные вам действия с переменной file (иначе потеряете информацию). Впрочем, можно обойтись и без close, используя связку операторов with as (переменная, которая ссылается на файл, должна быть прописана после конструкции):
with open("otus.txt", "w") as file: file.write("hello world")Метод write() для записи в файл в Python
В предыдущих примерах мы уже использовали метод write(). Он позволяет записывать любую строку в открытый файл. Помните, что строки в Python способны содержать не только текст, но и двоичные данные.
Запись в файл построчно выполняется посредством записи нужной вам строки с последующей записью \n— символа перевода строки.
Давайте ещё раз посмотрим на запись в файл с помощью метода write().
Синтаксис:Пример использования:
my_file = open("otus.txt", "w") my_file.write("Люблю Python!\nЭто крутой язык!") my_file.close()Код, представленный выше, создаст файл otus.txt , записав в него указанную строку.
Давайте теперь выполним запись списка поэлементно, где каждый элемент списка будет записан в новой строке:
lines = ["one", "two", "three"] with open(r"C:\otus.txt", "w") as file: for line in lines: file.write(line + '\n')Этот код позволит создать небольшой массив lines, содержащий три строковых элемента: «one», «two» и «three». Благодаря функции open и связке операторов with as произойдёт открытие текстового файла otus.txt в корневом каталоге жёсткого диска C. Далее произойдёт запись всех элементов списка с помощью write. Символ \n обеспечит, чтобы каждая запись была выполнена с новой строки.
Основы работы с файлами в Python
Михаил Свинцов
автор курса «Full-stack веб-разработчик на Python»
Взаимодействие с файловой системой позволяет хранить информацию, полученную в результате работы программы. Михаил Свинцов из SkillFactory расскажет о базовой функциональности языка программирования Python для работы с файлами.
Встроенные средства Python
Основа для работы с файлами — built-in функция
open()
open(file, mode="rt")
Эта функция имеет два аргумента. Аргумент
file
принимает строку, в которой содержится путь к файлу. Второй аргумент,mode
, позволяет указать режим, в котором необходимо работать с файлом. По умолчанию этот аргумент принимает значение «rt», с которым, и с некоторыми другими, можно ознакомиться в таблице нижеЭти режимы могут быть скомбинированы. Например, «rb» открывает двоичный файл для чтения. Комбинируя «r+» или «w+» можно добиться открытия файла в режиме и чтения, и записи одновременно с одним отличием — первый режим вызовет исключение, если файла не существует, а работа во втором режиме в таком случае создаст его.
Начать саму работу с файлом можно с помощью объекта класса
io.TextIOWrapper
, который возвращается функциейopen()
. У этого объекта есть несколько атрибутов, через которые можно получить информацию
name
— название файла;mode
— режим, в котором этот файл открыт;closed
— возвращаетTrue
, если файл был закрыт.
По завершении работы с файлом его необходимо закрыть при помощи метода close()
f = open("examp.le", "w")
// работа с файлом
f.close()
Однако более pythonic way стиль работы с файлом встроенными средствами заключается в использовании конструкции with .. as ..
, которая работает как менеджер создания контекста. Написанный выше пример можно переписать с ее помощью
with open("examp.le", "w") as f:
// работа с файлом
Главное отличие заключается в том, что python самостоятельно закрывает файл, и разработчику нет необходимости помнить об этом. И бонусом к этому не будут вызваны исключения при открытии файла (например, если файл не существует).
Чтение из файла
При открытии файла в режимах, допускающих чтение, можно использовать несколько подходов.
Для начала можно прочитать файл целиком и все данные, находящиеся в нем, записать в одну строку.
with open("examp.le", "r") as f:
text = f.read()
Используя эту функцию с целочисленным аргументом, можно прочитать определенное количество символов.
with open("examp.le", "r") as f:
part = f.read(16)
При этом будут получены только первые 16 символов текста. Важно понимать, что при применении этой функции несколько раз подряд будет считываться часть за частью этого текста — виртуальный курсор будет сдвигаться на считанную часть текста. Его можно сдвинуть на определенную позицию, при необходимости воспользовавшись методом seek()
.
with open("examp.le", "r") as f: # 'Hello, world!'
first_part = f.read(8) # 'Hello, w'
f.seek(4)
second_part = f.read(8) # 'o, world'
Другой способ заключается в считывании файла построчно. Метод readline()
считывает строку и, также как и с методом read()
, сдвигает курсор — только теперь уже на целую строку. Применение этого метода несколько раз будет приводить к считыванию нескольких строк. Схожий с этим способом, другой метод позволяет прочитать файл целиком, но по строкам, записав их в список. Этот список можно использовать, например, в качестве итерируемого объекта в цикле.
with open("examp.le", "r") as f:
for line in f.readlines():
print(line)
Однако и здесь существует более pythonic way. Он заключается в том, что сам объект io.TextIOWrapper
имеет итератор, возвращающий строку за строкой. Благодаря этому нет необходимости считывать файл целиком, сохраняя его в список, а можно динамически по строкам считывать файл. И делать это лаконично.
with open("examp.le", "r") as f:
for line in f:
print(line)
Запись в файл
Функциональность внесения данных в файл не зависит от режима — добавление данных или перезаписывание файла. В выполнении этой операции также существует несколько подходов.
Самый простой и логичный — использование функции write()
with open("examp.le", "w") as f:
f.write(some_string_data)
Важно, что в качестве аргумента функции могут быть переданы только строки. Если необходимо записать другого рода информацию, то ее необходимо явно привести к строковому типу, используя методы __str__(self)
для объектов или форматированные строки.
Есть возможность записать в файл большой объем данных, если он может быть представлен в виде списка строк.
with open("examp.le", "w") as f:
f.writelines(list_of_strings)
Здесь есть еще один нюанс, связанный с тем, что функции write()
и writelines()
автоматически не ставят символ переноса строки, и это разработчику нужно контролировать самостоятельно.
Существует еще один, менее известный, способ, но, возможно, самый удобный из представленных. И как бы не было странно, он заключается в использовании функции print()
. Сначала это утверждение может показаться странным, потому что общеизвестно, что с помощью нее происходит вывод в консоль. И это правда. Но если передать в необязательный аргумент file
объект типа io.TextIOWrapper
, каким и является объект файла, с которым мы работаем, то поток вывода функции print()
перенаправляется из консоли в файл.
with open("examp.le", "w") as f:
print(some_data, file=f)
Сила такого подхода заключается в том, что в print()
можно передавать не обязательно строковые аргументы — при необходимости функция сама их преобразует к строковому типу.
На этом знакомство с базовой функциональностью работы с файлами можно закончить. Вместе с этим стоит сказать, что возможности языка Python им не ограничивается. Существует большое количество библиотек, которые позволяют работать с файлами определенных типов, а также допускают более тесное взаимодействие с файловой системой. И в совокупности они предоставляют разработчикам легкий и комфортный способ работы с файлами.
Запись в определенную строку файла на Python
Файл — это просто последовательность байтов, среди которых встречаются переносы строк. Т.е. если вы работаете с файлом:
строка 1
строчка 2
строка 3
…то на самом деле на диске лежит последовательность байтов:
строка 1␊строчка 2␊строка 3
Вы можете перезаписать некоторые байты, не пересчитывая/перезаписывая весь файл, как внутри строки, так и между строк, например:
строка 1␊XXXXXXXXXXXтрока 3
тогда, просматривая файл по строкам, вы увидите:
строка 1
XXXXXXXXXXXтрока 3
…но никак нельзя удалить кусок из середины файла, ничего не делая с той частью, которая идет после удаляемого куска.
Вы можете построить код таким образом, чтобы читать из файла строки по одной и писать их сразу же в файл на новое место, например, если удаляем строку 1:
читаем «строка 1», пропускаем:
↓ позиция для чтения строка 1␊строчка 2␊строка 3 ↑ позиция для записи
читаем «строчка 2»:
↓ позиция для чтения строка 1␊строчка 2␊строка 3 ↑ позиция для записи
Записываем «строчка 2» на новое место:
↓ позиция для чтения строчка 2␊трочка 2␊строка 3 ↑ позиция для записи
Аналогично, читаем «строка 3» и пишем ее на новое место:
↓ позиция для чтения строчка 2␊строка 3␊строка 3 ↑ позиция для записи
Обрезаем ненужное место в конце файла:
строчка 2␊строка 3␊
Если вы хотите не удалять строку, а вместо одной строки писать другую, то надо быть внимательным в случае если новая строка длиннее старой. На этот случай примера кода у меня нет.
Как видно, плоские файлы — неудачный способ хранения большого объема данных, если нужно что-то менять «посередине». Если вы сами создаете этот файл, возможно стоит рассмотреть другие форматы хранения, более эффективные для нужных вам операций.
python — Записать результат работы функции в файл
Можно в самом начале переопределить функцию print
old_print = print # Запоминаем старую функцию print
def print(*args, **kwargs): # Переопределяем
if "file" not in kwargs: # Если не передали параметр file
with open("filename", "a") as fp: # Будем записывать в файл filename
old_print(*args, **kwargs, file=fp)
else:
old_print(*args, **kwargs) # Иначе будем записывать в file, который передали
Но это очень плохая практика. Если кто-то будет смотреть Ваш код (возможно даже Вы сами через некоторое время), то Вам за это «спасибо» не скажут.
Другой способ: можно просто перенаправить stdout в файл. Для этого можно просто запустить скрипт так:
python script.py > filename
Тем самым всё будет печататься не в консоль, а в файл filename
.
UPD (уже неактуально, но пусть будет)
Если Вы хотите выполнить только одну функцию из скрипта, то придётся в самом скрипте подключать модуль sys
(встроенный) и смотреть параметры, переданные скрипту из командой строки. Например:
import sys
def func1(*args):
print(args) # Функционал функции
def func2(*args):
print(args) # Функционал функции
# ...
def run_all_funcs(): # запускает все функции
func1()
func2()
# ...
if __name__ == "__main__":
if len(sys.argv) == 2: # Проверяем кол-во аргументов,
# переданных скрипту из командой строки
if sys.argv[1] == "func1":
func1()
if sys.argv[1] == "func2":
func2()
# ...
else: # Если аргументов не передали, то запускаем все функции
run_all_funcs()
И запуск тогда будет такой:
python script.py func2 > filename
Надеюсь, суть ясна.
UUPD
Сразу не подумал, можно намного проще. Если в файле script.py
есть функция func(a, b)
, то только её можно вызвать так:
python -c "from script import *; func(1, 2)" > filename
Обратите внимание, что мы импортируем всё из файла script.py
, но расширение .py
не указываем.
Запись файлов — Документация Python для сетевых инженеров 3.0
При записи, очень важно определиться с режимом открытия файла, чтобы
случайно его не удалить:
w
— открыть файл для записи. Если файл существует, то его
содержимое удаляетсяa
— открыть файл для дополнения записи. Данные добавляются в
конец файла
При этом оба режима создают файл, если он не существует.
Для записи в файл используются такие методы:
write()
— записать в файл одну строкуwritelines()
— позволяет передавать в качестве аргумента список строк
write()
Метод write
ожидает строку, для записи.
Для примера, возьмем список строк с конфигурацией:
In [1]: cfg_lines = ['!', ...: 'service timestamps debug datetime msec localtime show-timezone year', ...: 'service timestamps log datetime msec localtime show-timezone year', ...: 'service password-encryption', ...: 'service sequence-numbers', ...: '!', ...: 'no ip domain lookup', ...: '!', ...: 'ip ssh version 2', ...: '!']
Открытие файла r2.txt в режиме для записи:
In [2]: f = open('r2.txt', 'w')
Преобразуем список команд в одну большую строку с помощью join
:
In [3]: cfg_lines_as_string = '\n'.join(cfg_lines) In [4]: cfg_lines_as_string Out[4]: '!\nservice timestamps debug datetime msec localtime show-timezone year\nservice timestamps log datetime msec localtime show-timezone year\nservice password-encryption\nservice sequence-numbers\n!\nno ip domain lookup\n!\nip ssh version 2\n!'
Запись строки в файл:
In [5]: f.write(cfg_lines_as_string)
Аналогично можно добавить строку вручную:
In [6]: f.write('\nhostname r2')
После завершения работы с файлом, его необходимо закрыть:
Так как ipython поддерживает команду cat, можно легко посмотреть
содержимое файла:
In [8]: cat r2.txt ! service timestamps debug datetime msec localtime show-timezone year service timestamps log datetime msec localtime show-timezone year service password-encryption service sequence-numbers ! no ip domain lookup ! ip ssh version 2 ! hostname r2
writelines()
Метод writelines()
ожидает список строк, как аргумент.
Запись списка строк cfg_lines в файл:
In [1]: cfg_lines = ['!', ...: 'service timestamps debug datetime msec localtime show-timezone year', ...: 'service timestamps log datetime msec localtime show-timezone year', ...: 'service password-encryption', ...: 'service sequence-numbers', ...: '!', ...: 'no ip domain lookup', ...: '!', ...: 'ip ssh version 2', ...: '!'] In [9]: f = open('r2.txt', 'w') In [10]: f.writelines(cfg_lines) In [11]: f.close() In [12]: cat r2.txt !service timestamps debug datetime msec localtime show-timezone yearservice timestamps log datetime msec localtime show-timezone yearservice password-encryptionservice sequence-numbers!no ip domain lookup!ip ssh version 2!
В результате все строки из списка записались в одну строку файла, так
как в конце строк не было символа \n
.
Добавить перевод строки можно по-разному.
Например, можно просто обработать список в цикле:
In [13]: cfg_lines2 = [] In [14]: for line in cfg_lines: ....: cfg_lines2.append( line + '\n' ) ....: In [15]: cfg_lines2 Out[15]: ['!\n', 'service timestamps debug datetime msec localtime show-timezone year\n', 'service timestamps log datetime msec localtime show-timezone year\n', 'service password-encryption\n', 'service sequence-numbers\n', '!\n', 'no ip domain lookup\n', '!\n', 'ip ssh version 2\n',
Если итоговый список записать заново в файл, то в нём уже
будут переводы строк:
In [18]: f = open('r2.txt', 'w') In [19]: f.writelines(cfg_lines2) In [20]: f.close() In [21]: cat r2.txt ! service timestamps debug datetime msec localtime show-timezone year service timestamps log datetime msec localtime show-timezone year service password-encryption service sequence-numbers ! no ip domain lookup ! ip ssh version 2 !
Изучаем Python: работа с файлами
В этой статье мы рассмотрим операции с файлами в Python. Открытие файла Python. Чтение из файла Python. Запись в файл Python, закрытие файла. А также методы, предназначенные для работы с файлами.
Файл – это именованная область диска, предназначенная для длительного хранения данных в постоянной памяти (например, на жёстком диске).
Чтобы прочитать или записать данные в файл, сначала нужно его открыть. После окончания работы файл необходимо закрыть, чтобы освободить связанные с ним ресурсы.
Поэтому в Python операции с файлами выполняются в следующем порядке:
- Открытие файла Python.
- Чтение из файла Python или запись в файл Python (выполнение операции).
- Закрытие файла Python.
Не знаете как открыть файл в питоне? В Python есть встроенная функция open(), предназначенная для открытия файла. Она возвращает объект, который используется для чтения или изменения файла.
>>> f = open("test.txt") # открыть файл в текущей папке >>> f = open("C:/Python33/README.txt") # указание полного пути
При этом можно указать необходимый режим открытия файла: ‘r’- для чтения,’w’ — для записи,’a’ — для изменения. Мы также можем указать, хотим ли открыть файл в текстовом или в бинарном формате.
По умолчанию файл открывается для чтения в текстовом режиме. При чтении файла в этом режиме мы получаем строки.
В бинарном формате мы получим байты. Этот режим используется для чтения не текстовых файлов, таких как изображения или exe-файлы.
Открытие файла Python- возможные режимы | |
Режим | Описание |
‘r’ | Открытие файла для чтения. Режим используется по умолчанию. |
‘w’ | Открытие файла для записи. Режим создаёт новый файл, если он не существует, или стирает содержимое существующего. |
‘x’ | Открытие файла для записи. Если файл существует, операция заканчивается неудачей (исключением). |
‘a’ | Открытие файла для добавления данных в конец файла без очистки его содержимого. Этот режим создаёт новый файл, если он не существует. |
‘t’ | Открытие файла в текстовом формате. Этот режим используется по умолчанию. |
‘b’ | Открытие файла в бинарном формате. |
‘+’ | Открытие файла для обновления (чтения и записи). |
f = open("test.txt") # эквивалент 'r' или 'rt' f = open("test.txt",'w') # запись в текстовом режиме f = open("img.bmp",'r+b') # чтение и запись в бинарном формате
В отличие от других языков программирования, в Python символ ‘a’ не подразумевает число 97, если оно не закодировано в ASCII (или другой эквивалентной кодировке).
Кодировка по умолчанию зависит от платформы. В Windows – это ‘cp1252’, а в Linux ‘utf-8’.
Поэтому мы не должны полагаться на кодировку по умолчанию. При работе с файлами в текстовом формате рекомендуется указывать тип кодировки.
f = open("test.txt",mode = 'r',encoding = 'utf-8')
Закрытие освободит ресурсы, которые были связаны с файлом. Это делается с помощью метода close(), встроенного в язык программирования Python.
В Python есть сборщик мусора, предназначенный для очистки ненужных объектов, Но нельзя полагаться на него при закрытии файлов.
f = open("test.txt",encoding = 'utf-8') # выполнение операций с файлом f.close()
Этот метод не полностью безопасен. Если при операции возникает исключение, выполнение будет прервано без закрытия файла.
Более безопасный способ – использование блока try…finally.
try: f = open("test.txt",encoding = 'utf-8') # выполнение операций с файлом finally: f.close()
Это гарантирует правильное закрытие файла даже после возникновения исключения, прерывающего выполнения программы.
Также для закрытия файла можно использовать конструкцию with. Оно гарантирует, что файл будет закрыт при выходе из блока with. При этом не нужно явно вызывать метод close(). Это будет сделано автоматически.
with open("test.txt",encoding = 'utf-8') as f: # выполнение операций с файлом
Чтобы записать данные в файл в Python, нужно открыть его в режиме ‘w’, ‘a’ или ‘x’. Но будьте осторожны с режимом ‘w’. Он перезаписывает файл, если то уже существует. Все данные в этом случае стираются.
Запись строки или последовательности байтов (для бинарных файлов) осуществляется методом write(). Он возвращает количество символов, записанных в файл.
with open("test.txt",'w',encoding = 'utf-8') as f: f.write("my first filen") f.write("This filenn") f.write("contains three linesn")
Эта программа создаст новый файл ‘test.txt’. Если он существует, данные файла будут перезаписаны. При этом нужно добавлять символы новой строки самостоятельно, чтобы разделять строки.
Чтобы осуществить чтение из файла Python, нужно открыть его в режиме чтения. Для этого можно использовать метод read(size), чтобы прочитать из файла данные в количестве, указанном в параметре size. Если параметр size не указан, метод читает и возвращает данные до конца файла.
>>> f = open("test.txt",'r',encoding = 'utf-8') >>> f.read(4) # чтение первых 4 символов 'This' >>> f.read(4) # чтение следующих 4 символов ' is ' >>> f.read() # чтение остальных данных до конца файла 'my first filenThis filencontains three linesn' >>> f.read() # дальнейшие попытки чтения возвращают пустую строку ''
Метод read() возвращает новые строки как ‘n’. Когда будет достигнут конец файла, при дальнейших попытках чтения мы получим пустые строки.
Чтобы изменить позицию курсора в текущем файле, используется метод seek(). Метод tell() возвращает текущую позицию курсора (в виде количества байтов).
>>> f.tell() # получаем текущую позицию курсора в файле 56 >>> f.seek(0) # возвращаем курсор в начальную позицию 0 >>> print(f.read()) # читаем весь файл This is my first file This file contains three lines
Мы можем прочитать файл построчно в цикле for.
>>> for line in f: ... print(line, end = '') ... This is my first file This file contains three lines
Извлекаемые из файла строки включают в себя символ новой строки ‘n’. Чтобы избежать вывода, используем пустой параметр end метода print(),.
Также можно использовать метод readline(), чтобы извлекать отдельные строки. Он читает файл до символа новой строки.
>>> f.readline() 'This is my first filen' >>> f.readline() 'This filen' >>> f.readline() 'contains three linesn' >>> f.readline() ''
Метод readlines() возвращает список оставшихся строк. Все эти методы чтения возвращают пустую строку, когда достигается конец файла.
>>> f.readlines() ['This is my first filen', 'This filen', 'contains three linesn']
Ниже приводится полный список методов для работы с файлами в текстовом режиме.
Python работа с файлами — методы | |
Метод | Описание |
close() | Закрытие файла. Не делает ничего, если файл закрыт. |
detach() | Отделяет бинарный буфер от TextIOBase и возвращает его. |
fileno() | Возвращает целочисленный дескриптор файла. |
flush() | Вызывает сброс данных (запись на диск) из буфера записи файлового потока. |
isatty() | Возвращает значение True, если файловый поток интерактивный. |
read(n) | Читает максимум n символов из файла. Читает до конца файла, если значение отрицательное или None. |
readable() | Возвращает значение True, если из файлового потока можно осуществить чтение. |
readline(n=-1) | Читает и возвращает одну строку из файла. Читает максимум n байт, если указано соответствующее значение. |
readlines(n=-1) | Читает и возвращает список строк из файла. Читает максимум n байт/символов, если указано соответствующее значение. |
seek(offset,from=SEEK_SET) | Изменяет позицию курсора. |
seekable() | Возвращает значение True, если файловый поток поддерживает случайный доступ. |
tell() | Возвращает текущую позицию курсора в файле. |
truncate(size=None) | Изменяет размер файлового потока до size байт. Если значение size не указано, размер изменяется до текущего положения курсора. |
writable() | Возвращает значение True, если в файловый поток может производиться запись. |
write(s) | Записывает строки s в файл и возвращает количество записанных символов. |
writelines(lines) | Записывает список строк lines в файл. |
Данная публикация является переводом статьи «Python File IO Read and Write Files in Python» , подготовленная редакцией проекта.
Запись в файл в Python
Python предоставляет встроенные функции для создания, записи и чтения файлов. Существует два типа файлов, которые могут обрабатываться в Python: обычные текстовые файлы и двоичные файлы (написанные на двоичном языке, нули и единицы).
- Текстовые файлы: В файлах этого типа каждая строка текста заканчивается специальным символом EOL (конец строки), который по умолчанию является символом новой строки (‘\ n’) в Python.
- Двоичные файлы: В файлах этого типа отсутствует терминатор для строки, и данные сохраняются после их преобразования в понятный для машины двоичный язык.
Примечание: Чтобы узнать больше об обработке файлов, щелкните здесь.
Оглавление
Режим доступа
Режимы доступа определяют тип операций, возможных в открытом файле. Это относится к тому, как файл будет использоваться после его открытия. Эти режимы также определяют расположение дескриптора файла в файле. Дескриптор файла подобен курсору, который определяет, откуда данные должны быть прочитаны или записаны в файле. Различные режимы доступа для чтения файла: —
- Только запись («w»): Откройте файл для записи.Для существующего файла данные усекаются и перезаписываются. Ручка находится в начале файла. Создает файл, если файл не существует.
- Запись и чтение («w +»): Откройте файл для чтения и записи. Для существующего файла данные усекаются и перезаписываются. Ручка находится в начале файла.
- Только добавление (‘a’): Откройте файл для записи. Если файл не существует, он создается. Ручка находится в конце файла.Записываемые данные будут вставлены в конце после существующих данных.
Примечание: Чтобы узнать больше о режиме доступа, щелкните здесь.
Открытие файла
Это делается с помощью функции open ()
. Для этой функции импорт модуля не требуется.
Синтаксис:
File_object = open (r "Имя_файла", "Режим_доступа")
Файл должен существовать в том же каталоге, что и программный файл python, иначе полный адрес файла должен быть записан вместо имени файла.
Примечание: r
помещается перед именем файла, чтобы символы в строке имени файла не рассматривались как специальные символы. Например, если в адресе файла есть \ temp, то \ t рассматривается как символ табуляции и возникает ошибка недопустимого адреса. R делает строку необработанной, то есть сообщает, что в строке нет специальных символов. Букву r можно игнорировать, если файл находится в том же каталоге, а адрес не помещается.
|
Здесь file1 создается как объект для MyFile1 и file2 как объект для MyFile2.
Закрытие файла
close () Функция
закрывает файл и освобождает полученное пространство памяти этим файлом.Он используется тогда, когда файл больше не нужен или если его нужно открыть в другом файловом режиме.
Синтаксис:
File_object.close ()
|
Запись в файл
Есть два способа записи в файл.
- write (): Вставляет строку str1 в одну строку в текстовый файл.
File_object.write (str1)
- writelines (): Для списка строковых элементов каждая строка вставляется в текстовый файл. Используется для одновременной вставки нескольких строк.
File_object.writelines (L) для L = [str1, str2, str3]
Примечание. ‘\ n’
обрабатывается как специальный двухбайтовый символ.
Пример:
|
Выход:
Привет Это Дели Это париж Это лондон
Добавление к файлу
Когда файл открывается в режиме добавления, дескриптор располагается в конце файла.Записываемые данные будут вставлены в конце после существующих данных. Давайте посмотрим на пример ниже, чтобы прояснить разницу между режимом записи и режимом добавления.
|
Выход:
Вывод строк чтения после добавления Это Дели Это париж Это лондон Сегодня Вывод строк чтения после записи Завтра
С оператором
с оператором
в Python используется при обработке исключений, чтобы сделать код более чистым и читабельным.Это упрощает управление общими ресурсами, такими как файловые потоки. В отличие от описанных выше реализаций, при использовании оператора with нет необходимости вызывать file.close ()
. с заявлением
само по себе обеспечивает правильное получение и высвобождение ресурсов.
Синтаксис:
с открытым именем файла в виде файла:
|
Выход:
Привет Это Дели Это париж Это лондон
Примечание: Чтобы узнать больше о выписке, нажмите здесь.
7. Ввод и вывод — документация Python 3.9.4
Есть несколько способов представить вывод программы; данные можно распечатать
в удобочитаемой форме или записаны в файл для использования в будущем. В этой главе будет
обсудите некоторые возможности.
7.1. Более простое форматирование вывода
До сих пор мы встречали два способа записи значений: операторов выражения и
функция print ()
. (Третий способ — использовать метод write ()
файловых объектов; на стандартный выходной файл можно ссылаться как на sys.stdout
.
Для получения дополнительной информации см. Справочник по библиотеке.)
Часто требуется больше контроля над форматированием вывода, чем просто
печать значений, разделенных пробелами.Форматировать вывод можно несколькими способами.
Чтобы использовать форматированные строковые литералы, начните строку
сf
илиF
перед открывающей кавычкой или тройной кавычкой.
Внутри этой строки вы можете написать выражение Python между{
и}
символы, которые могут относиться к переменным или буквальным значениям.>>> год = 2016 >>> event = 'Референдум' >>> f'Результаты {года} {события} ' 'Итоги референдума 2016 года'
ул.format ()
метод строк требует более ручного
усилие. Вы по-прежнему будете использовать{
и}
, чтобы отмечать, где переменная
будут заменены и могут предоставить подробные директивы форматирования,
но вам также потребуется предоставить информацию для форматирования.>>> yes_votes = 42_572_654 >>> no_votes = 43_132_495 >>> процент = yes_votes / (yes_votes + no_votes) >>> '{: -9} ДА голосов {: 2.2%}'. Формат (yes_votes, процент) 42572654 ДА голоса 49.67% '
Наконец, вы можете выполнять всю обработку строк самостоятельно, используя нарезку строк и
операции конкатенации для создания любого макета, который вы можете себе представить. В
строковый тип имеет несколько методов, которые выполняют полезные операции для заполнения
строки с заданной шириной столбца.
Если вам не нужен навороченный вывод, а просто нужно быстро отобразить некоторые
переменные для целей отладки, вы можете преобразовать любое значение в строку с помощью
функции repr ()
или str ()
.
Функция str ()
предназначена для возврата представлений значений, которые
довольно удобочитаемый, а repr ()
предназначен для генерации представлений
который может быть прочитан интерпретатором (или вызовет SyntaxError
, если
нет эквивалентного синтаксиса). Для объектов, не имеющих особого
представление для человеческого потребления, str ()
вернет то же значение, что и
репр ()
. Многие значения, такие как числа или структуры, такие как списки и
словари имеют одинаковое представление с использованием любой функции.Струны, в
в частности, имеют два различных представления.
Некоторые примеры:
>>> s = 'Привет, мир.' >>> ул. 'Привет мир.' >>> представитель (ы) "'Привет мир.'" >>> str (1/7) '0,14285714285714285' >>> х = 10 * 3,25 >>> y = 200 * 200 >>> s = 'Значение x равно' + repr (x) + ', а y равно' + repr (y) + '...' >>> печать (и) Значение x равно 32,5, а y равно 40000 ... >>> # Функция repr () строки добавляет строковые кавычки и обратную косую черту: ... hello = 'привет, мир \ n' >>> привет = repr (привет) >>> печать (привет) 'привет, мир \ n' >>> # Аргументом repr () может быть любой объект Python: ... repr ((x, y, ('спам', 'яйца'))) "(32,5, 40000, ('спам', 'яйца'))"
Модуль string
содержит класс Template
, который предлагает
еще один способ подставить значения в строки, используя заполнители, такие как
$ x
и заменяя их значениями из словаря, но предлагает гораздо меньше
контроль форматирования.
7.1.1. Форматированные строковые литералы
Форматированные строковые литералы (также называемые f-строками для
short) позволяют включать значение выражений Python внутри строки с помощью
добавляя к строке префикс f
или F
и записывая выражения как
{выражение}
.
За выражением может следовать необязательный спецификатор формата. Это позволяет больше
контроль над форматированием значения. В следующем примере число Пи округляется до
три знака после запятой:
>>> импорт математики >>> print (f'Значение числа пи приблизительно равно {math.pi: .3f}. ') Значение пи составляет приблизительно 3,142.
Передача целого числа после ':'
приведет к тому, что это поле будет минимальным
количество символов в ширину. Это полезно для выравнивания столбцов.
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678} >>> для имени, телефона в table.items (): ... print (f '{name: 10} ==> {phone: 10d}') ... Шёрд ==> 4127 Джек ==> 4098 Dcab ==> 7678
Для преобразования значения перед форматированием можно использовать другие модификаторы. '! A'
применяет ascii ()
, '! S'
применяет str ()
и '! R'
применяется repr ()
:
>>> животные = 'угри' >>> print (f'Мое судно на воздушной подушке полно {животных}. ') Мое судно на воздушной подушке полно угрей. >>> print (f'Мое судно на воздушной подушке полно {животных! r}. ') Мое судно на воздушной подушке полно угрей'.
Для получения информации об этих спецификациях формата см.
справочное руководство по мини-языку спецификации формата.
7.1.2. Метод String format ()
Базовое использование метода str.format ()
выглядит так:
>>> print ('Мы те {}, которые говорят "{}!". Format (' рыцари ',' Ни ')) Мы рыцари, которые говорят «Ни!»
Скобки и символы в них (называемые полями формата) заменяются на
объекты передаются в метод str.format ()
. Число в
скобки могут использоваться для обозначения позиции объекта, переданного в
ул.format ()
метод.
>>> print ('{0} и {1}'. Формат ('спам', 'яйца')) спам и яйца >>> print ('{1} и {0}'. format ('спам', 'яйца')) яйца и спам
Если аргументы ключевого слова используются в методе str.format ()
, их значения
упоминаются с использованием имени аргумента.
>>> print ('Эта {еда} есть {прилагательное}.'. Format ( ... food = 'spam', прилагательное = 'абсолютно ужасно')) Этот спам просто ужасен.
Позиционные аргументы и аргументы ключевого слова можно произвольно комбинировать:
>>> print ('История {0}, {1} и {other}.'.format (' Билл ',' Манфред ', other = 'Георг')) История Билла, Манфреда и Георга.
Если у вас действительно длинная строка формата, которую вы не хотите разделять, она
было бы неплохо, если бы вы могли ссылаться на переменные для форматирования по имени
вместо должности. Это можно сделать, просто передав dict и используя
квадратные скобки '[]'
для доступа к клавишам.
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} >>> print ('Джек: {0 [Джек]: d}; Шорд: {0 [Шорд]: d};' ... 'Dcab: {0 [Dcab]: d}'. Формат (таблица)) Джек: 4098; Шорд: 4127; Dcab: 8637678
Это также можно сделать, передав таблицу в качестве аргументов ключевого слова с «**»
обозначение.
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} >>> print ('Jack: {Jack: d}; Sjoerd: {Sjoerd: d}; Dcab: {Dcab: d}'. format (** таблица)) Джек: 4098; Шорд: 4127; Dcab: 8637678
Это особенно полезно в сочетании со встроенной функцией.
vars ()
, который возвращает словарь, содержащий все локальные переменные.
В качестве примера следующие строки создают аккуратно выровненный
набор столбцов с целыми числами и их квадратами и кубами:
>>> для x в диапазоне (1, 11): ... print ('{0: 2d} {1: 3d} {2: 4d}'. format (x, x * x, x * x * x)) ... 1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000
Полный обзор форматирования строк с помощью str.format ()
см.
Синтаксис строки формата.
7.1.3. Форматирование строки вручную
Вот та же таблица квадратов и кубов, отформатированная вручную:
>>> для x в диапазоне (1, 11): ... print (repr (x) .rjust (2), repr (x * x) .rjust (3), end = '') ... # Обратите внимание на использование 'end' в предыдущей строке ... печать (repr (x * x * x) .rjust (4)) ... 1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000
(обратите внимание, что один пробел между каждым столбцом был добавлен
способ print ()
работает: он всегда добавляет пробелы между своими аргументами.)
Метод str.rjust ()
строковых объектов выравнивает строку по правому краю в
поле заданной ширины, заполняя его пробелами слева. Есть
аналогичные методы str.ljust ()
и str.center ()
. Эти методы делают
ничего не пишут, они просто возвращают новую строку. Если входная строка слишком
long, они не усекают его, а возвращают без изменений; это испортит ваш
расположение столбцов, но обычно это лучше, чем альтернатива, которая была бы
ложь о стоимости.(Если вам действительно нужно усечение, вы всегда можете добавить
операция среза, как в x.ljust (n) [: n]
.)
Существует еще один метод, str.zfill ()
, который заполняет числовую строку на
осталось с нулями. Он разбирается в плюсах и минусах:
>>> '12'.zfill (5)
"00012"
>>> '-3.14'.zfill (7)
'-003,14'
>>> '3.141559'.zfill (5)
"3.141559"
7.1.4. Старое форматирование строки
Оператор% (по модулю) также может использоваться для форматирования строк.Учитывая 'строку'
, экземпляры
% значений %
в строке
заменяются нулем или более
элементы значений
. Эта операция широко известна как строка
интерполяция. Например:
>>> импорт математики >>> print ('Значение пи примерно% 5.3f.'% math.pi) Значение пи составляет приблизительно 3,142.
Дополнительную информацию можно найти в разделе «Форматирование строк в стиле printf».
7.2. Чтение и запись файлов
open ()
возвращает файловый объект и чаще всего используется с
два аргумента: открыть (имя файла, режим)
.
>>> f = open ('рабочий файл', 'w')
Первый аргумент - это строка, содержащая имя файла. Второй аргумент
другая строка, содержащая несколько символов, описывающих способ, которым файл
будет использовано. Режим может быть 'r'
, когда файл будет только читаться, 'w'
только для записи (существующий файл с таким же именем будет удален), и
'a'
открывает файл для добавления; любые данные, записанные в файл,
автоматически добавляется в конец. 'r +'
открывает файл как для чтения, так и для
письмо. Аргумент mode является необязательным; 'r'
будет считаться, если это
опущено.
Обычно файлы открываются в текстовом режиме , то есть вы читаете и пишете
строки из файла и в файл, которые закодированы в определенной кодировке. Если
кодировка не указана, значение по умолчанию зависит от платформы (см.
открытый ()
). 'b'
, добавленный к режиму, открывает файл в
двоичный режим : теперь данные читаются и записываются в виде байтов
объекты.Этот режим следует использовать для всех файлов, не содержащих текста.
В текстовом режиме при чтении по умолчанию выполняется преобразование строки, зависящей от платформы.
окончания ( \ n
в Unix, \ r \ n
в Windows) до \ n
. При записи в
текстовый режим, по умолчанию вхождения \ n
обратно в
окончание строк, зависящее от платформы. Эта закулисная модификация
в файл данных подходит для текстовых файлов, но приведет к повреждению двоичных данных, подобных этому в
JPEG
или EXE
файлов.Будьте очень осторожны при использовании двоичного режима, когда
чтение и запись таких файлов.
Рекомендуется использовать с ключевым словом
при работе с
с файловыми объектами. Преимущество в том, что файл правильно закрыт
после завершения его набора, даже если на каком-то
точка. Использование с
также намного короче, чем написание
эквивалент попытка
- наконец
блоков:
>>> с open ('workfile') как f: ... read_data = f.read () >>> # Мы можем проверить, что файл был автоматически закрыт.>>> f.closed Правда
Если вы не используете с ключевым словом
, вам следует позвонить
f.close ()
, чтобы закрыть файл и немедленно освободить любую систему
ресурсы, используемые им.
Предупреждение
Вызов f.write ()
без использования с ключевым словом
или вызова
f.close ()
может привести к аргументам
из f.write ()
не полностью записывается на диск, даже если
программа успешно завершается.
После закрытия файлового объекта либо с помощью оператора с оператором
или вызывая f.close ()
, попытки использовать файловый объект будут
автоматически терпит неудачу.
>>> f.close () >>> f.read () Отслеживание (последний вызов последний): Файл "", строка 1, в ValueError: операция ввода-вывода для закрытого файла.
7.2.1. Методы файловых объектов
В остальных примерах этого раздела предполагается, что файловый объект с именем
f
уже создан.
Чтобы прочитать содержимое файла, вызовите f.read (size)
, который читает некоторое количество
data и возвращает их в виде строки (в текстовом режиме) или байтового объекта (в двоичном режиме).
размер - необязательный числовой аргумент. Если размер опущен или отрицателен,
будет прочитано и возвращено все содержимое файла; это ваша проблема, если
размер файла вдвое превышает объем памяти вашего компьютера. В противном случае не более размер
символов (в текстовом режиме) или размером байт (в двоичном режиме) считываются и возвращаются.Если достигнут конец файла, f.read ()
вернет пустой
строка ( ''
).
>>> f.read () "Это весь файл. \ N" >>> f.read () ''
f.readline ()
читает одну строку из файла; символ новой строки ( \ n
)
остается в конце строки и опускается только в последней строке
file, если файл не заканчивается новой строкой. Это делает возвращаемое значение
однозначный; если f.readline ()
возвращает пустую строку, конец файла
достигнут, а пустая строка представлена '\ n'
, строка
содержащий только одну новую строку.
>>> f.readline () 'Это первая строка файла. \ N' >>> f.readline () 'Вторая строка файла \ n' >>> f.readline () ''
Для чтения строк из файла вы можете перебрать объект файла. Это память
эффективный, быстрый и простой код:
>>> для строки в f: ... печать (строка, конец = '') ... Это первая строка файла. Вторая строка файла
Если вы хотите прочитать все строки файла в списке, вы также можете использовать
список (f)
или f.Чтение линий ()
.
f.write (строка)
записывает содержимое строки в файл, возвращая
количество написанных символов.
>>> f.write ('Это тест \ n') 15
Остальные типы объектов необходимо преобразовать - либо в строку (в текстовом режиме)
или байтовый объект (в двоичном режиме) - перед их записью:
>>> value = ('ответ', 42) >>> s = str (value) # преобразовать кортеж в строку >>> е.написать (а) 18
f.tell ()
возвращает целое число, указывающее текущую позицию файлового объекта в файле.
представлен как количество байтов от начала файла в двоичном режиме и
непрозрачный номер в текстовом режиме.
Чтобы изменить положение файлового объекта, используйте f.seek (смещение, откуда)
. Позиция вычисляется
от добавления смещения к точке отсчета; точка отсчета выбирается
, откуда аргумент. , откуда значение 0 отсчитывает от начала
файла, 1 использует текущую позицию файла, а 2 использует конец файла как
ориентир., откуда можно опустить и по умолчанию 0, используя
начало файла в качестве ориентира.
>>> f = open ('рабочий файл', 'rb +') >>> f.write (b'0123456789abcdef ') 16 >>> f.seek (5) # Перейти к 6-му байту в файле 5 >>> f.read (1) b'5 ' >>> f.seek (-3, 2) # Перейти к 3-му байту до конца 13 >>> f.read (1) b'd '
В текстовых файлах (открытых без b
в строке режима) выполняется поиск только
относительно начала файла разрешены (исключение - поиск
до самого конца файла с seek (0, 2)
), и единственными допустимыми значениями смещения являются
те, что вернулись из f.tell ()
или ноль. Любое другое значение смещения дает
неопределенное поведение.
Файловые объекты имеют некоторые дополнительные методы, такие как isatty (),
и
truncate ()
, которые используются реже; консультируйтесь с библиотекой
Справочник для полного руководства по файловым объектам.
7.2.2. Сохранение структурированных данных с помощью
json
Строки можно легко записывать и читать из файла. Числа занимают немного больше
усилия, поскольку метод read ()
возвращает только строки, которые должны
передаваться в функцию типа int ()
, которая принимает строку типа '123'
и возвращает его числовое значение 123.Если вы хотите сохранить более сложные данные
типы, такие как вложенные списки и словари, парсинг и сериализация вручную
усложняется.
Вместо того, чтобы заставлять пользователей постоянно писать и отлаживать код для экономии
сложные типы данных в файлы, Python позволяет использовать популярные данные
формат обмена называется JSON (JavaScript Object Notation). Стандартный модуль под названием json
может принимать Python
иерархии данных и преобразовать их в строковые представления; этот процесс
вызвал сериализуя .Реконструкция данных из строкового представления
называется десериализацией . Между сериализацией и десериализацией
строка, представляющая объект, могла быть сохранена в файле или данных, или
отправлено через сетевое соединение на какую-то удаленную машину.
Примечание
Формат JSON обычно используется современными приложениями для обработки данных.
обмен. Многие программисты уже знакомы с ним, что делает
это хороший выбор для взаимодействия.
Если у вас есть объект размером x
, вы можете просмотреть его строковое представление JSON с
простая строка кода:
>>> импортировать json >>> json.дампы ([1, 'простой', 'список']) '[1, «простой», «список»] »
Другой вариант функции dumps ()
, называемый dump ()
,
просто сериализует объект в текстовый файл. Итак, если f
- это
объект текстового файла, открытый для записи, мы можем сделать это:
Для повторного декодирования объекта, если f
- объект текстового файла, имеющий
открыт для чтения:
Этот простой метод сериализации может обрабатывать списки и словари, но
сериализация произвольных экземпляров класса в JSON требует немного дополнительных усилий.Ссылка на модуль json
содержит объяснение этого.
См. Также
pickle
- модуль pickle
В отличие от JSON, pickle - это протокол, который позволяет
сериализация произвольно сложных объектов Python. Таким образом, это
специфичен для Python и не может использоваться для связи с приложениями
написано на других языках. По умолчанию это тоже небезопасно:
десериализация данных рассола, поступающих из ненадежного источника, может выполнить
произвольный код, если данные были созданы опытным злоумышленником.
Чтение и запись файлов на Python (Руководство) - Real Python
Смотреть сейчас Это руководство содержит соответствующий видеокурс, созданный командой Real Python. Посмотрите его вместе с письменным руководством, чтобы углубить свое понимание: Чтение и запись файлов на Python
Одна из наиболее распространенных задач, которые вы можете выполнять с помощью Python, - это чтение и запись файлов. Будь то запись в простой текстовый файл, чтение сложного журнала сервера или даже анализ необработанных байтовых данных, все эти ситуации требуют чтения или записи файла.
В этом руководстве вы узнаете:
- Из чего состоит файл и почему это важно в Python
- Основы чтения и записи файлов в Python
- Некоторые базовые сценарии чтения и записи файлов
Это руководство в основном предназначено для питонистов от начинающего до среднего уровня, но здесь есть несколько советов, которые могут быть оценены и более продвинутыми программистами.
Пройдите тест: Проверьте свои знания с помощью нашей интерактивной викторины «Чтение и запись файлов на Python».По завершении вы получите оценку, чтобы вы могли отслеживать свой прогресс в обучении с течением времени:
Пройдите тест »
Что такое файл?
Прежде чем мы сможем перейти к тому, как работать с файлами в Python, важно понять, что именно представляет собой файл и как современные операционные системы обрабатывают некоторые из их аспектов.
По своей сути файл представляет собой непрерывный набор байтов, используемых для хранения данных. Эти данные организованы в определенном формате и могут быть как простыми, как текстовый файл, так и сложными, как исполняемый файл программы.В конце эти байтовые файлы затем преобразуются в двоичные коды 1
и 0
для упрощения обработки компьютером.
Файлы в большинстве современных файловых систем состоят из трех основных частей:
- Заголовок: метаданные о содержимом файла (имя файла, размер, тип и т. Д.)
- Данные: содержимое файла, написанное создателем или редактором
- Конец файла (EOF): специальный символ, обозначающий конец файла
То, что представляют эти данные, зависит от используемой спецификации формата, которая обычно представлена расширением.Например, файл с расширением .gif
, скорее всего, соответствует спецификации формата обмена графическими данными. Существуют сотни, если не тысячи, расширений файлов. В этом руководстве вы будете иметь дело только с расширениями файлов .txt
или .csv
.
Пути к файлам
При доступе к файлу в операционной системе требуется указать путь к файлу. Путь к файлу - это строка, представляющая расположение файла. Он разбит на три основные части:
- Путь к папке: расположение папки с файлами в файловой системе, где последующие папки разделены косой чертой
/
(Unix) или обратной косой чертой\
(Windows) - Имя файла: фактическое имя файла
- Расширение: конец пути к файлу с точкой (
.
) используется для обозначения типа файла
Вот небольшой пример. Допустим, у вас есть файл, расположенный в такой файловой структуре:
/
│
├── путь /
| │
│ ├── к /
│ │ └── cats.gif
│ │
│ └── dog_breeds.txt
|
└── animals.csv
Допустим, вы хотите получить доступ к файлу cats.gif
, и ваше текущее местоположение было в той же папке, что и путь
. Чтобы получить доступ к файлу, вам нужно пройти через папку путь
, а затем папку с по
, наконец, дойдя до кошек.gif
файл. Путь к папке - путь / к /
. Имя файла - кошек
. Расширение файла - .gif
. Таким образом, полный путь - это путь / to / cats.gif
.
Теперь предположим, что ваше текущее местоположение или текущий рабочий каталог (cwd) находится в папке с по
структуры папок нашего примера. Вместо того, чтобы ссылаться на cats.gif
по полному пути path / to / cats.gif
, на файл можно просто ссылаться по имени файла и расширению cats.Гифка
.
/
│
├── путь /
| │
| ├── to / ← Ваш текущий рабочий каталог (cwd) здесь
| │ └── cats.gif ← Доступ к этому файлу
| │
| └── dog_breeds.txt
|
└── animals.csv
А как насчет dog_breeds.txt
? Как бы вы могли получить к нему доступ, не используя полный путь? Вы можете использовать специальные символы с двумя точками ( ..
) для перемещения на один каталог вверх. Это означает, что ../dog_breeds.txt
будет ссылаться на dog_breeds.txt
из каталога с по
:
/
│
├── путь / ← Ссылка на эту родительскую папку
| │
| ├── в / ← Текущий рабочий каталог (cwd)
| │ └── cats.gif
| │
| └── dog_breeds.txt ← Доступ к этому файлу
|
└── animals.csv
Двойная точка ( ..
) может быть объединена в цепочку для перемещения по нескольким каталогам над текущим каталогом. Например, чтобы получить доступ к файлу animals.csv
из папки с по
, вы должны использовать ../../animals.csv
.
Окончание строк
Одна из проблем, часто возникающих при работе с данными файла, - это представление новой строки или окончания строки. Окончание строки уходит корнями в эпоху азбуки Морзе, когда определенный про-знак использовался для обозначения конца передачи или конца строки.
Позже это было стандартизовано для телетайпов Международной организацией по стандартизации (ISO) и Американской ассоциацией стандартов (ASA).Стандарт ASA гласит, что в конце строки должна использоваться последовательность символов возврата каретки ( CR
или \ r
) и символов перевода строки ( LF
или \ n
) ( CR + LF
или \ г \ п
). Однако стандарт ISO допускает использование символов CR + LF
или только символа LF
.
Windows использует символы CR + LF
для обозначения новой строки, в то время как Unix и более новые версии Mac используют только символ LF
.Это может вызвать некоторые сложности при обработке файлов в операционной системе, отличной от исходной. Вот небольшой пример. Допустим, мы исследуем файл dog_breeds.txt
, который был создан в системе Windows:
Мопс \ r \ n
Джек Рассел Терьер \ r \ n
Английский спрингер-спаниель \ r \ n
Немецкая овчарка \ r \ n
Стаффордширский бультерьер \ r \ n
Кавалер кинг чарльз спаниель \ r \ n
Золотистый ретривер \ r \ n
Вест-хайленд-уайт-терьер \ r \ n
Боксёр \ r \ n
Бордер терьер \ r \ n
Этот же вывод будет интерпретироваться на устройстве Unix по-разному:
Мопс \ г
\ п
Джек Рассел терьер \ r
\ п
Английский спрингер-спаниель \ r
\ п
Немецкая овчарка \ r
\ п
Стаффордширский бультерьер \ r
\ п
Кавалер кинг чарльз спаниель \ r
\ п
Золотистый ретривер \ r
\ п
Вест-хайленд-уайт-терьер \ r
\ п
Боксёр \ r
\ п
Бордер терьер \ r
\ п
Это может сделать перебор каждой строки проблематичным, и вам, возможно, придется учитывать подобные ситуации.
Кодировки символов
Другая распространенная проблема, с которой вы можете столкнуться, - это кодирование байтовых данных. Кодировка - это перевод байтовых данных в символы, читаемые человеком. Обычно это делается путем присвоения числового значения для представления символа. Двумя наиболее распространенными кодировками являются форматы ASCII и UNICODE. ASCII может хранить только 128 символов, в то время как Unicode может содержать до 1114112 символов.
ASCII на самом деле является подмножеством Unicode (UTF-8), что означает, что ASCII и Unicode имеют одинаковые числовые и символьные значения.Важно отметить, что синтаксический анализ файла с неправильной кодировкой символов может привести к сбоям или искажению символа. Например, если файл был создан с использованием кодировки UTF-8, и вы пытаетесь проанализировать его с использованием кодировки ASCII, если есть символ, выходящий за пределы этих 128 значений, будет выдана ошибка.
Открытие и закрытие файла в Python
Если вы хотите работать с файлом, первое, что нужно сделать, это открыть его. Это делается путем вызова встроенной функции open ()
. open ()
имеет единственный обязательный аргумент - путь к файлу. open ()
имеет единственный возврат, файловый объект:
файл = открытый ('dog_breeds.txt')
После открытия файла нужно научиться закрывать его.
Предупреждение: Вы должны всегда убедиться, что открытый файл правильно закрыт.
Важно помнить, что вы несете ответственность за закрытие файла. В большинстве случаев после завершения работы приложения или скрипта файл в конечном итоге закрывается.Однако нет никакой гарантии, когда именно это произойдет. Это может привести к нежелательному поведению, включая утечку ресурсов. Также рекомендуется использовать Python (Pythonic), чтобы убедиться, что ваш код ведет себя хорошо определенным образом и снижает любое нежелательное поведение.
Когда вы манипулируете файлом, вы можете использовать два способа, чтобы убедиться, что файл закрыт должным образом, даже при возникновении ошибки. Первый способ закрыть файл - использовать блок try-finally
:
reader = open ('dog_breeds.текст')
пытаться:
# Здесь идет дальнейшая обработка файла
наконец-то:
reader.close ()
Если вы не знакомы с блоком try-finally
, ознакомьтесь с исключениями Python: введение.
Второй способ закрыть файл - использовать с оператором
:
с открытым ('dog_breeds.txt') в качестве читателя:
# Здесь идет дальнейшая обработка файла
Оператор с
автоматически закрывает файл, как только он покидает с блоком
, даже в случае ошибки.Я настоятельно рекомендую вам как можно чаще использовать с оператором
, так как он позволяет сделать код более чистым и упрощает обработку любых неожиданных ошибок.
Скорее всего, вы также захотите использовать второй позиционный аргумент, режим , режим
. Этот аргумент представляет собой строку, содержащую несколько символов, обозначающих способ открытия файла. По умолчанию и наиболее часто используется значение 'r'
, что означает открытие файла в режиме только для чтения в виде текстового файла:
с открытым ('dog_breeds.txt ',' r ') в качестве читателя:
# Здесь идет дальнейшая обработка файла
Другие варианты режимов полностью задокументированы в Интернете, но наиболее часто используются следующие:
Знак | Значение |
---|---|
'r' | Открыто для чтения (по умолчанию) |
'ширина' | Открыть для записи, обрезать (перезаписать) первый файл |
'rb' или 'wb' | Открыть в двоичном режиме (чтение / запись с использованием байтовых данных) |
Давайте вернемся и поговорим немного о файловых объектах.Файловый объект:
«объект, предоставляющий файловый API (с такими методами, как
read ()
илиwrite ()
) для базового ресурса». (Источник)
Есть три различных категории файловых объектов:
- Текстовые файлы
- Буферизованные двоичные файлы
- Необработанные двоичные файлы
Каждый из этих типов файлов определен в модуле io
. Вот краткое изложение того, как все выстраивается.
Типы текстовых файлов
Текстовый файл - это самый распространенный файл, с которым вы можете столкнуться. Вот несколько примеров того, как открываются эти файлы:
открыто ('abc.txt')
open ('abc.txt', 'r')
open ('abc.txt', 'ш')
С этими типами файлов open ()
вернет объект файла TextIOWrapper
:
>>>
>>> file = open ('dog_breeds.txt')
>>> тип (файл)
<класс '_io.TextIOWrapper'>
Это объект файла по умолчанию, возвращаемый функцией open ()
.
Типы буферизованных двоичных файлов
Буферизованный двоичный тип файла используется для чтения и записи двоичных файлов. Вот несколько примеров того, как открываются эти файлы:
открыто ('abc.txt', 'rb')
открыть ('abc.txt', 'wb')
С этими типами файлов open ()
вернет либо объект файла BufferedReader
, либо BufferedWriter
:
>>>
>>> file = open ('dog_breeds.txt', 'rb')
>>> тип (файл)
<класс '_io.BufferedReader '>
>>> file = open ('dog_breeds.txt', 'wb')
>>> тип (файл)
<класс '_io.BufferedWriter'>
Типы файлов Raw
Необработанный тип файла:
«обычно используется в качестве низкоуровневого строительного блока для двоичных и текстовых потоков». (Источник)
Поэтому обычно не используется.
Вот пример того, как открываются эти файлы:
открыть ('abc.txt', 'rb', буферизация = 0)
С этими типами файлов open ()
вернет объект файла FileIO
:
>>>
>>> file = open ('dog_breeds.txt ',' rb ', буферизация = 0)
>>> тип (файл)
<класс '_io.FileIO'>
Чтение и запись открытых файлов
Открыв файл, вы захотите прочитать или записать в файл. Во-первых, давайте рассмотрим чтение файла. Есть несколько методов, которые могут быть вызваны для файлового объекта, чтобы помочь вам:
Метод | Что он делает |
---|---|
.read (размер = -1) | Читается из файла на основе числа размером байта.Если аргумент не передан или Нет или -1 , то читается весь файл. |
. Строка чтения (размер = -1) | Считывает не более размера количества символов из строки. Это продолжается до конца строки, а затем возвращается обратно. Если аргумент не передан или Нет или -1 , то читается вся строка (или остальная часть строки). |
.readlines () | Это считывает оставшиеся строки из файлового объекта и возвращает их в виде списка. |
Используя тот же файл dog_breeds.txt
, который вы использовали выше, давайте рассмотрим несколько примеров использования этих методов. Вот пример того, как открыть и прочитать весь файл с помощью .read ()
:
.
>>>
>>> с open ('dog_breeds.txt', 'r') в качестве читателя:
>>> # Прочитать и распечатать весь файл
>>> print (reader.read ())
Мопс
Джек Рассел терьер
Английский спрингер-спаниель
Немецкая овчарка
Стаффордширский бультерьер
Кавалер кинг чарльз спаниель
Золотистый ретривер
Вест-хайленд-уайт-терьер
Боксер
Бордер терьер
Вот пример того, как каждый раз читать 5 байтов строки с помощью Python .readline ()
метод:
>>>
>>> с open ('dog_breeds.txt', 'r') в качестве читателя:
>>> # Прочтите и распечатайте первые 5 символов строки 5 раз
>>> print (reader.readline (5))
>>> # Обратите внимание, что строка больше 5 символов и продолжается
>>> # вниз по строке, читая каждый раз по 5 символов до конца
>>> # строка, а затем "оборачивается" вокруг
>>> print (reader.readline (5))
>>> напечатайте (читатель.readline (5))
>>> print (reader.readline (5))
>>> print (reader.readline (5))
Мопс
разъем
Russe
ll Te
Rrier
Вот пример того, как прочитать весь файл в виде списка с помощью метода Python .readlines ()
:
>>>
>>> f = open ('dog_breeds.txt')
>>> f.readlines () # Возвращает объект списка
['Мопс \ n', 'Джек-рассел-терьер \ n', 'Английский спрингер-спаниель \ n', 'Немецкая овчарка \ n', 'Стаффордширский бультерьер \ n', 'Кавалер-кинг Чарльз-спаниель \ n', 'Золотистый ретривер \ n ',' Вест-хайленд-уайт-терьер \ n ',' Боксер \ n ',' Бордер-терьер \ n ']
Приведенный выше пример также может быть выполнен с помощью list ()
для создания списка из файлового объекта:
>>>
>>> f = open ('dog_breeds.текст')
>>> список (е)
['Мопс \ n', 'Джек-рассел-терьер \ n', 'Английский спрингер-спаниель \ n', 'Немецкая овчарка \ n', 'Стаффордширский бультерьер \ n', 'Кавалер-кинг Чарльз-спаниель \ n', 'Золотистый ретривер \ n ',' Вест-хайленд-уайт-терьер \ n ',' Боксер \ n ',' Бордер-терьер \ n ']
Итерация по каждой строке в файле
Обычно при чтении файла выполняется итерация по каждой строке. Вот пример того, как использовать метод Python .readline ()
для выполнения этой итерации:
>>>
>>> с открытым ('dog_breeds.txt ',' r ') в качестве читателя:
>>> # Прочитать и распечатать весь файл построчно
>>> line = reader.readline ()
>>> while line! = '': # Символ EOF - это пустая строка
>>> печать (строка, конец = '')
>>> line = reader.readline ()
Мопс
Джек Рассел терьер
Английский спрингер-спаниель
Немецкая овчарка
Стаффордширский бультерьер
Кавалер кинг чарльз спаниель
Золотистый ретривер
Вест-хайленд-уайт-терьер
Боксер
Бордер терьер
Другой способ перебора каждой строки в файле - использовать Python .readlines ()
метод файлового объекта. Помните, что .readlines ()
возвращает список, в котором каждый элемент в списке представляет строку в файле:
>>>
>>> с open ('dog_breeds.txt', 'r') в качестве читателя:
>>> для строки в reader.readlines ():
>>> печать (строка, конец = '')
Мопс
Джек Рассел терьер
Английский спрингер-спаниель
Немецкая овчарка
Стаффордширский бультерьер
Кавалер кинг чарльз спаниель
Золотистый ретривер
Вест-хайленд-уайт-терьер
Боксер
Бордер терьер
Однако приведенные выше примеры можно еще больше упростить, перебирая сам файловый объект:
>>>
>>> с открытым ('dog_breeds.txt ',' r ') в качестве читателя:
>>> # Прочитать и распечатать весь файл построчно
>>> для строчки в ридере:
>>> печать (строка, конец = '')
Мопс
Джек Рассел терьер
Английский спрингер-спаниель
Немецкая овчарка
Стаффордширский бультерьер
Кавалер кинг чарльз спаниель
Золотистый ретривер
Вест-хайленд-уайт-терьер
Боксер
Бордер терьер
Этот последний подход является более питоническим и может быть более быстрым и более эффективным с точки зрения памяти. Поэтому рекомендуется использовать это вместо этого.
Примечание: Некоторые из приведенных выше примеров содержат print ('some text', end = '')
. end = ''
предотвращает добавление Python дополнительной строки в печатаемый текст и выводит только то, что читается из файла.
Теперь перейдем к написанию файлов. Как и при чтении файлов, файловые объекты имеют несколько методов, которые полезны для записи в файл:
Метод | Что он делает |
---|---|
.запись (строка) | Это записывает строку в файл. |
.writelines (seq) | Это записывает последовательность в файл. К каждому элементу последовательности не добавляются окончания строк. Вы можете добавить соответствующие окончания строки. |
Вот быстрый пример использования .write ()
и .writelines ()
:
с open ('dog_breeds.txt', 'r') в качестве читателя:
# Примечание: строки чтения не обрезают окончания строк
dog_breeds = читатель.readlines ()
с open ('dog_breeds_reversed.txt', 'w') в качестве писателя:
# В качестве альтернативы вы можете использовать
# writer.writelines (перевернутый (dog_breeds))
# Запишите породы собак в файл в обратном порядке
для породы реверс (dog_breeds):
писатель. писать (порода)
Работа с байтами
Иногда может потребоваться работа с файлами, использующими байтовые строки. Это делается путем добавления символа 'b'
к аргументу mode
. Применяются все те же методы для файлового объекта.Однако каждый из методов ожидает и вместо этого возвращает объект байт и
:
>>>
>>> с open ('dog_breeds.txt', 'rb') в качестве читателя:
>>> print (reader.readline ())
б'Мопс \ п '
Открытие текстового файла с помощью флага b
не так уж и интересно. Допустим, у нас есть эта симпатичная фотография джек-рассел-терьера ( jack_russell.png
):
Изображение: CC BY 3.0 (https://creativecommons.org/licenses/by/3.0)], из Wikimedia Commons
. Вы действительно можете открыть этот файл в Python и изучить его содержимое! Начиная с модели .Формат файла png
четко определен, заголовок файла состоит из 8 байт, разбитых следующим образом:
Значение | Устный перевод |
---|---|
0x89 | «Магическое» число, указывающее, что это начало PNG |
0x50 0x4E 0x47 | PNG в ASCII |
0x0D 0x0A | Строка в стиле DOS, заканчивающаяся \ r \ n |
0x1A | Символ EOF в стиле DOS |
0x0A | Строка в стиле Unix, заканчивающаяся \ n |
Конечно, когда вы открываете файл и читаете эти байты по отдельности, вы можете видеть, что это действительно .png
заголовочный файл:
>>>
>>> с open ('jack_russell.png', 'rb') как byte_reader:
>>> печать (byte_reader.read (1))
>>> печать (byte_reader.read (3))
>>> печать (byte_reader.read (2))
>>> печать (byte_reader.read (1))
>>> печать (byte_reader.read (1))
б '\ x89'
b'PNG '
б '\ г \ п'
б '\ x1a'
б '\ п'
Полный пример:
dos2unix.py
Давайте принесем все это домой и рассмотрим полный пример того, как читать и писать в файл.Ниже приведен инструмент, похожий на dos2unix
, который преобразует файл, содержащий окончания строк \ r \ n
, в \ n
.
Этот инструмент разбит на три основных раздела. Первый - это str2unix ()
, который преобразует строку из \ r \ n
окончания строки в \ n
. Второй - это dos2unix ()
, который преобразует строку, содержащую \ r \ n
символа, в \ n
. dos2unix ()
вызывает внутри себя str2unix ()
.Наконец, есть блок __main__
, который вызывается только тогда, когда файл выполняется как сценарий. Думайте об этом как об основной функции
, которую можно найти в других языках программирования.
"" "
Простой скрипт и библиотека для преобразования файлов или строк из dos, например
окончания строк в Unix, как окончания строк.
"" "
import argparse
импорт ОС
def str2unix (input_str: str) -> str:
р"""
Преобразует строку из концов строки \ r \ n в \ n
Параметры
----------
input_str
Строка, окончание строки которой будет преобразовано
Возврат
-------
Преобразованная строка
"" "
r_str = input_str.replace ('\ r \ n', '\ n')
вернуть r_str
def dos2unix (исходный_файл: стр., целевой_файл: стр.):
"" "
Преобразует файл, содержащий окончания строк в стиле Dos, в формат Unix, например
Параметры
----------
исходный файл
Путь к исходному файлу, который нужно преобразовать
dest_file
Путь к преобразованному файлу для вывода
"" "
# ПРИМЕЧАНИЕ: можно добавить проверку существования файла и перезапись файла
# защита
с open (source_file, 'r') в качестве читателя:
dos_content = reader.read ()
unix_content = str2unix (dos_content)
с open (dest_file, 'w') как писатель:
писатель.написать (unix_content)
если __name__ == "__main__":
# Создадим наш парсер аргументов и зададим его описание
parser = argparse.ArgumentParser (
description = "Скрипт, преобразующий файл, подобный DOS, в файл, подобный Unix",
)
# Добавьте аргументы:
# - source_file: исходный файл, который мы хотим преобразовать
# - dest_file: место назначения, куда должен идти вывод
# Примечание: использование типа аргумента argparse.FileType может
# оптимизировать некоторые вещи
parser.add_argument (
'исходный файл',
help = 'Местоположение источника'
)
парсер.add_argument (
'--dest_file',
help = 'Расположение файла назначения (по умолчанию: исходный_файл с добавлением _unix' ',
по умолчанию = Нет
)
# Разбираем аргументы (argparse автоматически берет значения из
# sys.argv)
args = parser.parse_args ()
s_file = args.source_file
d_file = args.dest_file
# Если целевой файл не был передан, предположим, что мы хотим
# создаем новый файл на основе старого
если d_file - None:
file_path, file_extension = os.path.splitext (s_file)
d_file = f '{file_path} _unix {file_extension}'
dos2unix (s_file, d_file)
Советы и хитрости
Теперь, когда вы освоили основы чтения и записи файлов, вот несколько советов и приемов, которые помогут вам развить свои навыки.
__file__
Атрибут __file__
- это специальный атрибут модулей, аналогичный __name__
. Это:
«путь к файлу, из которого был загружен модуль, если он был загружен из файла.»(Источник
Примечание: Чтобы повторить итерацию, __file__
возвращает путь относительно к тому месту, где был вызван исходный скрипт Python. Если вам нужен полный системный путь, вы можете использовать os.getcwd ()
, чтобы получить текущий рабочий каталог вашего исполняемого кода.
Вот пример из реальной жизни. На одной из моих прошлых работ я провел несколько тестов для аппаратного устройства. Каждый тест был написан с использованием скрипта Python с именем файла тестового скрипта, используемым в качестве заголовка.Затем эти сценарии будут выполнены и смогут распечатать свой статус с помощью специального атрибута __file__
. Вот пример структуры папок:
проект /
|
├── тесты /
| ├── test_commanding.py
| ├── test_power.py
| ├── test_wireHousing.py
| └── test_leds.py
|
└── main.py
Запуск main.py
дает следующее:
>>> python main.py
tests / test_commanding.py Начато:
tests / test_commanding.py Пройдено!
тесты / test_power.py Начато:
tests / test_power.py Пройдено!
tests / test_wireHousing.py Начато:
tests / test_wireHousing.py Ошибка!
tests / test_leds.py Начато:
tests / test_leds.py Пройдено!
Мне удалось запустить и получить статус всех моих тестов динамически с помощью специального атрибута __file__
.
Добавление к файлу
Иногда может потребоваться добавить в файл или начать запись в конце уже заполненного файла. Это легко сделать с помощью символа 'a'
в качестве аргумента mode
:
с открытым ('dog_breeds.txt ',' a ') как a_writer:
a_writer.write ('\ nБигл')
Когда вы снова изучите dog_breeds.txt
, вы увидите, что начало файла не изменилось, и теперь в конец файла добавлен Beagle
:
>>>
>>> с open ('dog_breeds.txt', 'r') в качестве читателя:
>>> print (reader.read ())
Мопс
Джек Рассел терьер
Английский спрингер-спаниель
Немецкая овчарка
Стаффордширский бультерьер
Кавалер кинг чарльз спаниель
Золотистый ретривер
Вест-хайленд-уайт-терьер
Боксер
Бордер терьер
Бигль
Работа с двумя файлами одновременно
Бывают случаи, когда вы можете одновременно прочитать файл и записать в другой файл.Если вы воспользуетесь примером, который был показан, когда вы учились писать в файл, его фактически можно объединить в следующее:
d_path = 'dog_breeds.txt'
d_r_path = 'dog_breeds_reversed.txt'
с open (d_path, 'r') как читатель, open (d_r_path, 'w') как писатель:
dog_breeds = reader.readlines ()
writer.writelines (перевернутый (dog_breeds))
Создание собственного диспетчера контекста
Может наступить время, когда вам понадобится более тонкий контроль над файловым объектом, поместив его в специальный класс.Когда вы это сделаете, использование с оператором
больше нельзя будет использовать, если вы не добавите несколько магических методов: __enter__
и __exit__
. Добавив их, вы создадите так называемый диспетчер контекста.
__enter __ ()
вызывается при вызове с оператором
. __exit __ ()
вызывается при выходе из с блоком операторов
.
Вот шаблон, который можно использовать для создания собственного класса:
класс my_file_reader ():
def __init __ (self, file_path):
себя.__path = путь к файлу
self .__ file_object = Нет
def __enter __ (сам):
self .__ file_object = open (собственный .__ путь)
вернуть себя
def __exit __ (self, type, val, tb):
сам .__ file_object.close ()
# Дополнительные методы, реализованные ниже
Теперь, когда у вас есть собственный класс, который теперь является диспетчером контекста, вы можете использовать его аналогично встроенному open ()
:
с my_file_reader ('dog_breeds.txt') в качестве читателя:
# Выполнение пользовательских операций класса
проходить
Вот хороший пример.Помните милый образ Джека Рассела, который у нас был? Возможно, вы хотите открыть другие файлы .png и
, но не хотите каждый раз анализировать файл заголовка. Вот пример того, как это сделать. В этом примере также используются настраиваемые итераторы. Если вы не знакомы с ними, ознакомьтесь с Python Iterators:
.
класс PngReader ():
# Каждый файл .png содержит это в заголовке. Используйте это, чтобы проверить
# файл действительно имеет формат .png.
_expected_magic = b '\ x89PNG \ r \ n \ x1a \ n'
def __init __ (self, file_path):
# Убедитесь, что файл имеет правильное расширение
если не file_path.заканчивается с ('. png'):
поднять NameError ("Файл должен иметь расширение .png")
self .__ path = file_path
self .__ file_object = Нет
def __enter __ (сам):
self .__ file_object = open (self .__ путь, 'rb')
magic = self .__ file_object.read (8)
если магия! = self._expected_magic:
Raise TypeError ("Файл не является правильно отформатированным файлом .png!")
вернуть себя
def __exit __ (self, type, val, tb):
сам .__ file_object.close ()
def __iter __ (сам):
# This и __next __ () используются для создания собственного итератора
# См. Https: // dbader.org / blog / python-итераторы
вернуть себя
def __next __ (сам):
# Прочитать файл в "Chunks"
# См. Https://en.wikipedia.org/wiki/Portable_Network_Graphics#%22Chunks%22_within_the_file
исходные_данные = сам .__ файл_объект.read (4)
# Файл не был открыт или не достиг EOF. Это означает, что мы
# дальше идти нельзя, поэтому остановите итерацию, подняв
# StopIteration.
если self .__ file_object равно None или initial_data == b '':
поднять StopIteration
еще:
# У каждого чанка есть len, тип, данные (на основе len) и crc
# Захватываем эти значения и возвращаем их как кортеж
chunk_len = int.from_bytes (начальные_данные, byteorder = 'большой')
chunk_type = self .__ file_object.read (4)
chunk_data = self .__ file_object.read (chunk_len)
chunk_crc = self .__ file_object.read (4)
вернуть chunk_len, chunk_type, chunk_data, chunk_crc
Теперь вы можете открывать файлов .png,
и правильно их анализировать с помощью настраиваемого диспетчера контекста:
>>>
>>> с PngReader ('jack_russell.png') в качестве читателя:
>>> для l, t, d, c в читателе:
>>> print (f "{l: 05}, {t}, {c}")
00013, b'IHDR ', b'v \ x121k'
00001, b'sRGB ', b' \ xae \ xce \ x1c \ xe9 '
00009, b'pHYs ', b' (<] \ x19 '
00345, b'iTXt ', b "L \ xc2'Y"
16384, b'IDAT ', b'i \ x99 \ x0c ('
16384, b'IDAT ', b' \ xb3 \ xfa \ x9a $ '
16384, b'IDAT ', b' \ xff \ xbf \ xd1 \ n '
16384, b'IDAT ', b' \ xc3 \ x9c \ xb1} '
16384, b'IDAT ', b' \ xe3 \ x02 \ xba \ x91 '
16384, b'IDAT ', b' \ xa0 \ xa99 = '
16384, b'IDAT ', b' \ xf4 \ x8b.\ x92 '
16384, b'IDAT ', b' \ x17i \ xfc \ xde '
16384, b'IDAT ', b' \ x8fb \ x0e \ xe4 '
16384, b'IDAT ', b') 3 = {'
01040, b'IDAT ', b' \ xd6 \ xb8 \ xc1 \ x9f '
00000, b'IEND ', b' \ xaeB` \ x82 '
Не изобретайте змею заново
Есть типичные ситуации, с которыми вы можете столкнуться при работе с файлами. Большинство этих случаев можно обработать с помощью других модулей. Вам могут понадобиться два распространенных типа файлов: .csv
и .json
. Real Python уже собрал несколько отличных статей о том, как с этим справиться:
Кроме того, существуют встроенные библиотеки, которые вы можете использовать, чтобы помочь вам:
-
wave
: чтение и запись файлов WAV (аудио) -
aifc
: чтение и запись файлов AIFF и AIFC (аудио) -
sunau
: чтение и запись файлов Sun AU -
tarfile
: чтение и запись файлов tar-архива -
zipfile
: работа с ZIP-архивами -
configparser
: легко создавать и анализировать файлы конфигурации -
xml.etree.ElementTree
: создание или чтение файлов на основе XML -
msilib
: чтение и запись файлов установщика Microsoft -
plistlib
: создание и анализ файлов Mac OS X.plist
Есть еще много всего. Кроме того, в PyPI доступно еще больше сторонних инструментов. Вот некоторые популярные:
Ты файловый мастер, Гарри!
Вы сделали это! Теперь вы знаете, как работать с файлами с помощью Python, включая некоторые продвинутые методы.Работа с файлами в Python теперь должна быть проще, чем когда-либо, и это приятное чувство, когда вы начинаете это делать.
Из этого руководства вы узнали:
- Что это за файл
- Как правильно открывать и закрывать файлы
- Как читать и писать файлы
- Некоторые передовые методы работы с файлами
- Некоторые библиотеки для работы с общими типами файлов
Если у вас есть вопросы, пишите нам в комментариях.
Пройдите тест: Проверьте свои знания с помощью нашей интерактивной викторины «Чтение и запись файлов на Python».По завершении вы получите оценку, чтобы вы могли отслеживать свой прогресс в обучении с течением времени:
Пройдите тест »
Смотреть сейчас Это руководство содержит соответствующий видеокурс, созданный командой Real Python. Посмотрите его вместе с письменным руководством, чтобы углубить свое понимание: Чтение и запись файлов на Python
Чтение и запись файлов в Python
Файлы
Файлы - это места на диске, в которых хранится соответствующая информация.Они используются для постоянного хранения данных в энергонезависимой памяти (например, на жестком диске).
Поскольку оперативная память (RAM) является энергозависимой (которая теряет свои данные при выключении компьютера), мы используем файлы для будущего использования данных, постоянно сохраняя их.
Когда мы хотим читать или записывать в файл, нам нужно сначала открыть его. Когда мы закончим, его нужно закрыть, чтобы освободить ресурсы, связанные с файлом.
Следовательно, в Python файловая операция выполняется в следующем порядке:
- Открыть файл
- Чтение или запись (выполнение операции)
- Закройте файл
Открытие файлов в Python
Python имеет встроенную функцию open ()
для открытия файла.Эта функция возвращает файловый объект, также называемый дескриптором, поскольку он используется для чтения или изменения файла соответственно.
>>> f = open ("test.txt") # открыть файл в текущем каталоге
>>> f = open ("C: /Python38/README.txt") # указание полного пути
Мы можем указать режим при открытии файла. В режиме мы указываем, хотим ли мы прочитать r
, записать w
или добавить в файл и
. Мы также можем указать, хотим ли мы открыть файл в текстовом или двоичном режиме.
По умолчанию чтение в текстовом режиме. В этом режиме мы получаем строки при чтении из файла.
С другой стороны, двоичный режим возвращает байты, и это режим, который следует использовать при работе с нетекстовыми файлами, такими как изображения или исполняемые файлы.
Режим | Описание |
---|---|
r | Открывает файл для чтения. (по умолчанию) |
w | Открывает файл для записи.Создает новый файл, если он не существует, или обрезает файл, если он существует. |
x | Открывает файл для монопольного создания. Если файл уже существует, операция не выполняется. |
а | Открывает файл для добавления в конец файла без его усечения. Создает новый файл, если он не существует. |
т | Открывается в текстовом режиме. (по умолчанию) |
б | Открывается в двоичном режиме. |
+ | Открывает файл для обновления (чтения и записи) |
f = open ("test.txt") # эквивалентно 'r' или 'rt'
f = open ("test.txt", 'w') # писать в текстовом режиме
f = open ("img.bmp", 'r + b') # чтение и запись в двоичном режиме
В отличие от других языков, символ a
не подразумевает число 97, пока он не будет закодирован с использованием ASCII
(или других эквивалентных кодировок).
Более того, кодировка по умолчанию зависит от платформы. В Windows это cp1252
, но utf-8
в Linux.
Итак, мы не должны также полагаться на кодировку по умолчанию, иначе наш код будет вести себя по-разному на разных платформах.
Следовательно, при работе с файлами в текстовом режиме настоятельно рекомендуется указывать тип кодировки.
f = open ("test.txt", mode = 'r', encoding = 'utf-8')
Закрытие файлов в Python
Когда мы закончили выполнение операций с файлом, нам нужно правильно закрыть файл.
Закрытие файла освободит ресурсы, которые были связаны с файлом. Это делается с помощью метода close ()
, доступного в Python.
Python имеет сборщик мусора для очистки объектов, на которые нет ссылок, но мы не должны полагаться на него при закрытии файла.
f = open ("test.txt", encoding = 'utf-8')
# выполнять файловые операции
f.close ()
Этот метод не совсем безопасен. Если при выполнении какой-либо операции с файлом возникает исключение, код завершается без закрытия файла.
Более безопасный способ - использовать блок try ... finally.
попробуйте:
f = open ("test.txt", encoding = 'utf-8')
# выполнять файловые операции
наконец-то:
f.close ()
Таким образом, мы гарантируем, что файл будет правильно закрыт, даже если возникает исключение, вызывающее остановку выполнения программы.
Лучший способ закрыть файл - использовать с оператором
. Это гарантирует, что файл будет закрыт при выходе из блока внутри с оператором
.
Нам не нужно явно вызывать метод close ()
. Это делается изнутри.
с open ("test.txt", encoding = 'utf-8') как f:
# выполняем файловые операции
Запись в файлы на Python
Чтобы записать в файл на Python, нам нужно открыть его в режиме записи w
, добавить в
или исключить создание в режиме x
.
Мы должны быть осторожны с режимом w
, так как он будет перезаписан в файл, если он уже существует.Благодаря этому стираются все предыдущие данные.
Запись строки или последовательности байтов (для двоичных файлов) выполняется с помощью метода write ()
. Этот метод возвращает количество символов, записанных в файл.
с open ("test.txt", 'w', encoding = 'utf-8') как f:
f.write ("мой первый файл \ n")
f.write ("Этот файл \ n \ n")
f.write ("содержит три строки \ n")
Эта программа создаст новый файл с именем test.txt
в текущем каталоге, если он не существует.Если он существует, он перезаписывается.
Мы должны сами включить символы новой строки, чтобы различать разные строки.
Чтение файлов в Python
Чтобы прочитать файл на Python, мы должны открыть файл в режиме чтения r
.
Для этого доступны различные методы. Мы можем использовать метод read (size)
, чтобы читать данные размером , размер . Если параметр size не указан, он читает и возвращает до конца файла.
Мы можем прочитать файл text.txt
, который мы написали в предыдущем разделе, следующим образом:
>>> f = open ("test.txt", 'r', encoding = 'utf-8')
>>> f.read (4) # читать первые 4 данных
'Этот'
>>> f.read (4) # читать следующие 4 данных
' является '
>>> f.read () # читать остаток до конца файла
'мой первый файл \ nЭтот файл \ nсодержит три строки \ n'
>>> f.read () # дальнейшее чтение возвращает пустое жало
'
Мы видим, что метод read ()
возвращает новую строку как '\ n'
.По достижении конца файла при дальнейшем чтении мы получаем пустую строку.
Мы можем изменить текущий файловый курсор (позицию) с помощью метода seek ()
. Точно так же метод tell ()
возвращает нашу текущую позицию (в байтах).
>>> f.tell () # получить текущую позицию в файле
56
>>> f.seek (0) # переводим файловый курсор в исходную позицию
0
>>> print (f.read ()) # читать весь файл
Это мой первый файл
Этот файл
содержит три строки
Мы можем читать файл построчно, используя цикл for.Это одновременно эффективно и быстро.
>>> для строки в f:
... печать (строка, конец = '')
...
Это мой первый файл
Этот файл
содержит три строки
В этой программе строки в самом файле содержат символ новой строки \ n
. Итак, мы используем конечный параметр функции print ()
, чтобы избежать появления двух символов новой строки при печати.
В качестве альтернативы мы можем использовать метод readline ()
для чтения отдельных строк файла.Этот метод читает файл до новой строки, включая символ новой строки.
>>> f.readline ()
'Это мой первый файл \ n'
>>> f.readline ()
'Этот файл \ n'
>>> f.readline ()
'содержит три строки \ n'
>>> f.readline ()
'
Наконец, метод readlines ()
возвращает список оставшихся строк всего файла. Все эти методы чтения возвращают пустые значения, когда достигается конец файла (EOF).
>>> ф.readlines ()
['Это мой первый файл \ n', 'Этот файл \ n', 'содержит три строки \ n']
Методы файла Python
С файловым объектом доступны различные методы. Некоторые из них были использованы в приведенных выше примерах.
Вот полный список методов в текстовом режиме с кратким описанием:
Метод | Описание |
---|---|
закрыть () | Закрывает открытый файл. Не действует, если файл уже закрыт. |
отсоединить () | Отделяет базовый двоичный буфер от TextIOBase и возвращает его. |
fileno () | Возвращает целое число (дескриптор файла) файла. |
промывка () | Очищает буфер записи файлового потока. |
isatty () | Возвращает Истина , если файловый поток является интерактивным. |
читать ( n ) | Читает не более n символов из файла.Читает до конца файла, если оно отрицательное или Нет . |
читаемый () | Возвращает Истина , если файловый поток может быть прочитан. |
строка чтения ( n = -1) | Читает и возвращает одну строку из файла. Считывает не более n байт, если указано. |
строка чтения ( n = -1) | Читает и возвращает список строк из файла. Считывает не более n байт / символов, если указано. |
поиск ( смещение , от = SEEK_SET ) | Изменяет позицию файла на , смещение байт, по отношению к с (начало, текущее, конец). |
для поиска () | Возвращает True , если файловый поток поддерживает произвольный доступ. |
телл () | Возвращает текущее местоположение файла. |
обрезать ( размер = Нет ) | Изменяет размер файлового потока до , размер байт.Если размер не указан, изменяется в соответствии с текущим местоположением. |
с возможностью записи () | Возвращает Истина , если файловый поток может быть записан. |
запись ( с ) | Записывает в файл строку s и возвращает количество записанных символов. |
линий записи ( строк ) | Записывает в файл список из строк . |
python - правильный способ записи строки в файл?
Если вы пишете много данных и скорость вызывает беспокойство, вам, вероятно, следует использовать f.напишите (...)
. Я провел быстрое сравнение скорости, и он был значительно быстрее, чем print (..., file = f)
при выполнении большого количества операций записи.
время импорта
start = start = time.time ()
с open ("test.txt", 'w') как f:
для i в диапазоне (10000000):
# print ('Это тест скорости', file = f)
# f.write ('Это тест скорости \ n')
конец = время.время ()
печать (конец - начало)
В среднем запись
закончилась за 2,45 секунды на моей машине, тогда как печать
заняла примерно в 4 раза больше времени (9.76с). При этом в большинстве реальных сценариев это не будет проблемой.
Если вы выберете print (..., file = f)
, вы, вероятно, обнаружите, что время от времени хотите подавлять новую строку или заменять ее чем-то другим. Это можно сделать, установив необязательный параметр end
, например;
с открытым ("тест", 'w') как f:
print ('Foo1,', файл = f, конец = '')
print ('Foo2,', файл = f, конец = '')
print ('Foo3', файл = f)
Какой бы способ вы ни выбрали, я бы предложил использовать с
, поскольку это значительно упрощает чтение кода.
Обновление : Эта разница в производительности объясняется тем фактом, что запись
имеет высокую степень буферизации и возвращается до того, как на самом деле произойдут какие-либо записи на диск (см. Этот ответ), тогда как print
(вероятно) использует буферизацию строк. Простым тестом для этого может быть проверка производительности при длительной записи, где недостатки (с точки зрения скорости) буферизации строк будут менее выражены.
начало = начало = время.время ()
long_line = 'Это тест скорости' * 100
с открытым ("test.txt ", 'w') как f:
для i в диапазоне (1000000):
# print (long_line, file = f)
# f.write (long_line + '\ n')
конец = время.время ()
print (конец - начало, "с")
Разница в производительности теперь становится гораздо менее заметной: среднее время составляет 2,20 с для записи
и 3,10 с для печати
. Если вам нужно объединить кучу строк, чтобы получить эту длинную строку, производительность пострадает, поэтому варианты использования, когда print
будет более эффективным, немного редки.
Python Запись в файл - объяснение функций открытия, чтения, добавления и других функций обработки файлов
Добро пожаловать!
Привет! Если вы хотите научиться работать с файлами в Python, эта статья для вас. Работа с файлами - важный навык, которому должен овладеть каждый разработчик Python, поэтому приступим.
Из этой статьи вы узнаете:
- Как открыть файл.
- Как читать файл.
- Как создать файл.
- Как изменить файл.
- Как закрыть файл.
- Как открывать файлы для нескольких операций.
- Как работать с методами файлового объекта.
- Как удалить файлы.
- Как работать с менеджерами контекста и чем они полезны.
- Как обрабатывать исключения, которые могут возникать при работе с файлами.
- и больше!
Начнем! ✨
🔹 Работа с файлами: основной синтаксис
Одна из наиболее важных функций, которые вам нужно будет использовать при работе с файлами в Python, - это open ()
, встроенная функция, которая открывает файл и позволяет вашей программе использовать его и работать с ним.
Это основной синтаксис :
💡 Совет: Это два наиболее часто используемых аргумента для вызова этой функции. Есть шесть дополнительных необязательных аргументов. Чтобы узнать о них больше, прочтите эту статью в документации.
Первый параметр: файл
Первый параметр функции open ()
- это файл
, абсолютный или относительный путь к файлу, с которым вы пытаетесь работать.
Обычно мы используем относительный путь, который указывает, где расположен файл относительно местоположения скрипта (файла Python), который вызывает функцию open ()
.
Например, путь в этом вызове функции:
open ("names.txt") # Относительный путь - "names.txt"
Содержит только имя файла. Это можно использовать, когда файл, который вы пытаетесь открыть, находится в том же каталоге или папке, что и сценарий Python, например:
Но если файл находится во вложенной папке, например:
Файл names.txt в папке «data»
Затем нам нужно использовать определенный путь, чтобы сообщить функции, что файл находится в другой папке.
В этом примере это будет путь:
open ("data / names.txt")
Обратите внимание, что сначала мы пишем data /
(имя папки, за которым следует /
), а затем names.txt
(имя файла с расширением).
💡 Совет: Три буквы .txt
, следующие за точкой в names.txt
, являются «расширением» файла или его типом. В этом случае .txt
означает, что это текстовый файл.
Второй параметр: Mode
Второй параметр функции open ()
- это mode
, строка из одного символа. Этот единственный символ в основном сообщает Python, что вы планируете делать с файлом в своей программе.
Доступные режимы:
- Чтение (
"r"
). - Добавить (
"a"
) - Запись (
"w"
) - Создать (
"x"
)
Вы также можете открыть файл в:
- Текстовом режиме (
"t"
) - Двоичный режим (
"b"
)
Чтобы использовать текстовый или двоичный режим, вам нужно добавить эти символы в основной режим.Например: «wb»
означает запись в двоичном режиме.
💡 Совет: Режимы по умолчанию - это чтение ( "r"
) и текст ( "t"
), что означает "открыт для чтения текста" ( "rt"
), поэтому вы не необходимо указать их в open ()
, если вы хотите их использовать, потому что они назначаются по умолчанию. Вы можете просто написать open (<файл>)
.
Почему именно режимы?
Для Python действительно имеет смысл предоставлять только определенные разрешения в зависимости от того, что вы планируете делать с файлом, верно? Почему Python должен позволять вашей программе делать больше, чем необходимо? В основном поэтому существуют режимы.
Подумайте об этом - позволить программе делать больше, чем необходимо, может быть проблематичным. Например, если вам нужно только прочитать содержимое файла, может быть опасно позволить вашей программе неожиданно изменить его, что потенциально может привести к ошибкам.
🔸 Как читать файл
Теперь, когда вы знаете больше об аргументах, которые принимает функция open ()
, давайте посмотрим, как вы можете открыть файл и сохранить его в переменной для использования в своей программе. .
Это основной синтаксис:
Мы просто присваиваем значение, возвращаемое переменной.Например:
names_file = open ("data / names.txt", "r")
Я знаю, что вы можете спросить: какой тип значения возвращает open ()
?
Ну, файл объект .
Давайте немного поговорим о них.
Файловые объекты
Согласно документации Python, файловый объект - это:
Объект, предоставляющий файловый API (с такими методами, как read () или write ()) для базового ресурса.
По сути, это говорит нам о том, что файловый объект - это объект, который позволяет нам работать и взаимодействовать с существующими файлами в нашей программе Python.
Файловые объекты имеют такие атрибуты, как:
- имя : имя файла.
- закрыто :
Истинно
, если файл закрыт.Неверно
иначе. - режим : режим, используемый для открытия файла.
Например:
f = open ("данные / имена.txt "," а ")
print (f.mode) # Вывод: "a"
Теперь давайте посмотрим, как вы можете получить доступ к содержимому файла через файловый объект.
Методы чтения файла
Чтобы мы могли работать с файловыми объектами, нам нужен способ «взаимодействовать» с ними в нашей программе, и это именно то, что делают методы. Посмотрим на некоторые из них.
Read ()
Первый метод, о котором вам нужно узнать, - это read ()
, , который возвращает все содержимое файла в виде строки.
Вот пример:
f = open ("data / names.txt")
print (f.read ())
Результат:
Нора
Джино
Тимми
William
Вы можете использовать функцию type ()
, чтобы подтвердить, что значение, возвращаемое функцией f.read ()
, является строкой:
print (type (f.read ()))
# Выход
Да, это строка!
В этом случае был напечатан весь файл, потому что мы не указали максимальное количество байтов, но мы тоже можем это сделать.
Вот пример:
f = open ("data / names.txt")
print (f.read (3))
Возвращаемое значение ограничено этим количеством байтов:
Nor
❗️ Важно: Вам нужно закрыть файл после завершения задачи, чтобы освободить ресурсы, связанные с файлом. Для этого вам нужно вызвать метод close ()
, например:
Readline () vs. Readlines ()
С помощью этих двух методов вы можете читать файл построчно.Они немного отличаются, поэтому давайте рассмотрим их подробнее.
readline ()
читает одну строку файла, пока не достигнет конца этой строки. Завершающий символ новой строки ( \ n
) сохраняется в строке.
💡 Совет: При желании вы можете передать размер, максимальное количество символов, которое вы хотите включить в результирующую строку.
Например:
f = open ("data / names.txt")
печать (f.readline ())
f.close ()
Результат:
Нора
Это первая строка файла.
Напротив, readlines ()
возвращает список со всеми строками файла как отдельными элементами (строками). Это синтаксис:
Например:
f = open ("data / names.txt")
печать (f.readlines ())
f.close ()
Результат:
['Нора \ n', 'Джино \ n', 'Тимми \ n', 'Уильям']
Обратите внимание, что есть \ n
(символ новой строки) в конце каждой строки, кроме последней.
💡 Совет: Вы можете получить тот же список со списком (f)
.
Вы можете работать с этим списком в своей программе, назначая его переменной или используя его в цикле:
f = open ("data / names.txt")
для строки в f.readlines ():
# Сделайте что-нибудь с каждой строкой
f.close ()
Мы также можем перебирать f
напрямую (файловый объект) в цикле:
f = open ("data / names.txt", "r")
для строки в f:
# Сделайте что-нибудь с каждой строкой
f.close ()
Это основные методы, используемые для чтения файловых объектов. Теперь посмотрим, как можно создавать файлы.
🔹 Как создать файл
Если вам нужно создать файл "динамически" с помощью Python, вы можете сделать это в режиме "x"
.
Посмотрим как. Это основной синтаксис:
Вот пример. Это мой текущий рабочий каталог:
Если я запустил эту строку кода:
f = open ("new_file.txt", "x")
Будет создан новый файл с таким именем:
С этим В режиме вы можете создать файл, а затем динамически записать в него данные, используя методы, которым вы научитесь всего за несколько минут.
💡 Совет: Файл будет изначально пустым, пока вы его не измените.
Любопытно, что если вы попытаетесь запустить эту строку еще раз, а файл с таким именем уже существует, вы увидите следующую ошибку:
Traceback (последний вызов последним):
Файл «<путь>», строка 8, в <модуле>
f = open ("новый_файл.txt", "x")
FileExistsError: [Errno 17] Файл существует: 'new_file.txt'
Согласно документации Python, это исключение (ошибка времени выполнения):
Возникает при попытке создать файл или каталог, который уже существует.
Теперь, когда вы знаете, как создать файл, давайте посмотрим, как вы можете его изменить.
🔸 Как изменить файл
Чтобы изменить (записать) файл, вам необходимо использовать метод write ()
. У вас есть два способа сделать это (добавить или записать) в зависимости от режима, который вы выбрали для его открытия. Посмотрим на них подробнее.
Приложение
«Добавление» означает добавление чего-либо в конец другого предмета. Режим "a"
позволяет открывать файл для добавления к нему некоторого содержимого.
Например, если у нас есть этот файл:
И мы хотим добавить к нему новую строку, мы можем открыть его, используя режим "a"
(добавить), а затем вызвать команду записи ( )
, передавая контент, который мы хотим добавить в качестве аргумента.
Это основной синтаксис для вызова метода write ()
:
Вот пример:
f = open ("data / names.txt", "a")
f.write ("\ nНовая строка")
f.close ()
💡 Совет: Обратите внимание, что я добавляю \ n
перед строкой, чтобы указать, что я хочу, чтобы новая строка отображалась как отдельная строка, а не как продолжение существующей строки.
Теперь это файл после запуска сценария:
💡 Совет: Новая строка может не отображаться в файле до запуска f.close ()
.
Написать
Иногда вам может потребоваться удалить содержимое файла и полностью заменить его новым содержимым.Вы можете сделать это с помощью метода write ()
, если вы откроете файл в режиме "w"
.
Вот этот текстовый файл:
Если я запустил этот скрипт:
f = open ("data / names.txt", "w")
f.write («Новый контент»)
f.close ()
Это результат:
Как видите, открытие файла в режиме "w"
с последующей записью в него заменяет существующее содержимое.
💡 Совет: Метод write ()
возвращает количество записанных символов.
Если вы хотите написать несколько строк одновременно, вы можете использовать метод writelines ()
, который принимает список строк. Каждая строка представляет собой строку, которую нужно добавить в файл.
Вот пример. Это исходный файл:
Если мы запустим этот скрипт:
f = open ("data / names.txt", "a")
f.writelines (["\ nline1", "\ nline2", "\ nline3"])
f.close ()
Строки добавляются в конец файла:
Открыть файл для нескольких операций
Теперь вы знаете, как создавать, читать и записывать в файл, но что, если вы хотите сделать более одного объекта в одной программе? Давайте посмотрим, что произойдет, если мы попытаемся сделать это с режимами, которые вы уже изучили:
Если вы откроете файл в режиме "r"
(чтение), а затем попытаетесь записать в него:
f = open ("данные / имена.текст")
f.write ("New Content") # Пытаюсь написать
f.close ()
Вы получите следующую ошибку:
Traceback (последний вызов последний):
Файл «<путь>», строка 9, в <модуле>
f.write («Новый контент»)
io.UnsupportedOperation: не доступен для записи
Аналогично, если вы откроете файл в режиме "w"
(запись), а затем попытаетесь его прочитать:
f = open ("data / names.txt", " w ")
print (f.readlines ()) # Пытаюсь прочитать
f.write («Новый контент»)
f.close ()
Вы увидите эту ошибку:
Traceback (последний вызов последний):
Файл «<путь>», строка 14, в <модуле>
печать (f.readlines ())
io.UnsupportedOperation: не читается
То же самое произойдет с режимом "a"
(добавление).
Как мы можем это решить? Чтобы иметь возможность читать файл и выполнять другую операцию в той же программе, вам необходимо добавить в режим символ "+"
, например:
f = open ("data / names.txt", " w + ") # Чтение + Запись
f = open (" data / names.txt "," a + ") # Чтение + Добавление
f = open (" data / names.txt "," r + ") # Чтение + запись
Очень полезно, не так ли? Это, вероятно, то, что вы будете использовать в своих программах, но обязательно включайте только те режимы, которые вам нужны, чтобы избежать потенциальных ошибок.
Иногда файлы больше не нужны. Давайте посмотрим, как удалить файлы с помощью Python.
🔹 Как удалить файлы
Чтобы удалить файл с помощью Python, вам необходимо импортировать модуль под названием os
, который содержит функции, которые взаимодействуют с вашим Операционная система.
💡 Совет: Модуль - это файл Python со связанными переменными, функциями и классами.
В частности, вам понадобится функция remove ()
. Эта функция принимает путь к файлу в качестве аргумента и автоматически удаляет файл.
Давайте посмотрим на пример. Мы хотим удалить файл с именем sample_file.txt
.
Для этого напишем такой код:
import os
os.remove ("файл_выпуска.txt ")
- Первая строка:
import os
называется« оператором импорта ». Этот оператор записывается в верхней части файла и дает вам доступ к функциям, определенным в модулеos
. - Вторая строка:
os.remove ("sample_file.txt")
удаляет указанный файл.
💡 Совет: вы можете использовать абсолютный или относительный путь.
Теперь, когда вы знаете, как удалять файлы , посмотрим интересный инструмент... Менеджеры контекста!
🔸 Познакомьтесь с менеджерами контекста
Менеджеры контекста - это конструкции Python, которые сделают вашу жизнь намного проще. Используя их, вам не нужно помнить о закрытии файла в конце вашей программы, и у вас есть доступ к файлу в конкретной части программы, которую вы выбираете.
Синтаксис
Это пример диспетчера контекста, используемого для работы с файлами:
💡 Совет: Тело диспетчера контекста должно иметь отступ, точно так же, как мы делаем отступ для циклов, функций и классов.Если код без отступа, он не будет считаться частью диспетчера контекста.
Когда тело диспетчера контекста завершено, файл автоматически закрывается.
с open ("<путь>", "<режим>") как :
# Работа с файлом ...
# Здесь файл закрыт!
Пример
Вот пример:
с open ("data / names.txt", "r +") как f:
print (f.readlines ())
Этот диспетчер контекста открывает имена .txt
для операций чтения / записи и назначает этот файловый объект переменной f
. Эта переменная используется в теле диспетчера контекста для ссылки на файловый объект.
Попытка прочитать его снова
После того, как тело было завершено, файл автоматически закрывается, поэтому его нельзя прочитать, не открывая его снова. Но ждать! У нас есть строка, которая пытается прочитать его снова, прямо здесь, ниже:
с open ("data / names.txt", "r +") как f:
печать (f.readlines ())
печать (f.readlines ()) # Попытка прочитать файл снова, вне диспетчера контекста
Посмотрим, что произойдет:
Traceback (последний вызов последним):
Файл «<путь>», строка 21, в <модуле>
печать (f.readlines ())
ValueError: операция ввода-вывода для закрытого файла.
Эта ошибка возникает из-за того, что мы пытаемся прочитать закрытый файл. Классно, правда? Менеджер контекста делает всю тяжелую работу за нас, он удобочитаем и лаконичен.
🔹 Как обрабатывать исключения при работе с файлами
При работе с файлами могут возникать ошибки.Иногда у вас может не быть необходимых разрешений для изменения файла или доступа к нему, или файл может даже не существовать.
Как программист, вы должны предвидеть эти обстоятельства и обрабатывать их в своей программе, чтобы избежать внезапных сбоев, которые определенно могут повлиять на работу пользователя.
Давайте посмотрим на некоторые из наиболее распространенных исключений (ошибок времени выполнения), которые вы можете обнаружить при работе с файлами:
FileNotFoundError
Согласно документации Python, это исключение:
Возникает, когда файл или каталог запрашивается, но не существует.
Например, если файл, который вы пытаетесь открыть, не существует в вашем текущем рабочем каталоге:
f = open ("names.txt")
Вы увидите эту ошибку:
Отслеживание (последний вызов последний):
Файл «<путь>», строка 8, в <модуле>
f = open ("names.txt")
FileNotFoundError: [Errno 2] Нет такого файла или каталога: 'names.txt'
Давайте разберем эту ошибку по строкам:
-
Файл «<путь>», строка 8, в <модуль>
.Эта строка сообщает вам, что ошибка возникла, когда выполнялся код файла, расположенного в<путь>
. В частности, когдастрока 8
была выполнена в<модуль>
. -
f = open ("names.txt")
. Это строка, которая вызвала ошибку. -
FileNotFoundError: [Errno 2] Нет такого файла или каталога: 'names.txt'
. В этой строке говорится, что возникло исключениеFileNotFoundError
из-за имен файла или каталога.txt
не существует.
💡 Совет: Python очень информативен с сообщениями об ошибках, верно? Это огромное преимущество в процессе отладки.
PermissionError
Это еще одно распространенное исключение при работе с файлами. Согласно документации Python, это исключение:
Возникает при попытке запустить операцию без соответствующих прав доступа - например, разрешений файловой системы.
Это исключение возникает, когда вы пытаетесь прочитать или изменить файл, для которого нет разрешения на доступ.Если вы попытаетесь это сделать, вы увидите эту ошибку:
Traceback (последний вызов последний):
Файл «<путь>», строка 8, в <модуле>
f = open ("<путь-к-файлу>")
PermissionError: [Errno 13] Permission denied: 'data'
IsADirectoryError
Согласно документации Python, это исключение:
Возникает, когда в каталоге запрашивается файловая операция.
Это конкретное исключение возникает, когда вы пытаетесь открыть каталог или работать с ним, а не с файлом, поэтому будьте очень осторожны с путем, который вы передаете в качестве аргумента.
Как обрабатывать исключения
Для обработки этих исключений можно использовать оператор try / except . С помощью этого оператора вы можете «сказать» своей программе, что делать в случае чего-то неожиданного.
Это основной синтаксис:
попробуйте:
# Попробуйте запустить этот код
кроме :
# Если возникает исключение этого типа, остановить процесс и перейти к этому блоку
Здесь вы можете увидеть пример с FileNotFoundError
:
попробуйте:
f = open ("имена.текст")
кроме FileNotFoundError:
print («Файл не существует»)
В основном это говорит:
- Попробуйте открыть файл
names.txt
. - Если выдается
FileNotFoundError
, не сбой! Просто распечатайте описательное заявление для пользователя.
💡 Совет: Вы можете выбрать, как справиться с ситуацией, написав соответствующий код в блоке , кроме блока
. Возможно, вы могли бы создать новый файл, если он еще не существует.
Для автоматического закрытия файла после выполнения задачи (независимо от того, было ли вызвано исключение в блоке try
), вы можете добавить блок finally
.
попробуйте:
# Попробуйте запустить этот код
кроме <исключение>:
# Если возникает это исключение, немедленно остановить процесс и перейти к этому блоку
наконец-то:
# Сделайте это после запуска кода, даже если возникло исключение
Это пример:
попробуйте:
f = open ("имена.текст")
кроме FileNotFoundError:
print («Файл не существует»)
наконец-то:
f.close ()
Есть много способов настроить оператор try / except / finally, и вы даже можете добавить блок else
для запуска блока кода, только если в блоке try
не возникло никаких исключений.
💡 Совет: Чтобы узнать больше об обработке исключений в Python, вы можете прочитать мою статью: «Как обрабатывать исключения в Python: подробное визуальное введение».
🔸 Вкратце
- Вы можете создавать, читать, записывать и удалять файлы с помощью Python.
- Файловые объекты имеют собственный набор методов, которые вы можете использовать для работы с ними в своей программе.
- Контекстные менеджеры помогают работать с файлами и управлять ими, автоматически закрывая их после завершения задачи.
- Обработка исключений - это ключевой момент в Python. Общие исключения при работе с файлами включают
FileNotFoundError
,PermissionError
иIsADirectoryError
.С ними можно справиться с помощью try / except / else / finally.
Я очень надеюсь, что вам понравилась моя статья и вы нашли ее полезной. Теперь вы можете работать с файлами в своих проектах Python. Ознакомьтесь с моими онлайн-курсами. Подпишись на меня в Твиттере. ⭐️
Запись файлов с использованием Python
Как указывалось в предыдущей статье, посвященной чтению данных из файлов, обработка файлов относится к важным знаниям каждого профессионального программиста Python.Эта функция является основной частью языка Python, и для ее правильной загрузки не требуется загружать дополнительный модуль.
Основы написания файлов на Python
Общие методы работы с файлами: open (),
, чтобы открыть файл, seek (),
, чтобы установить текущую позицию файла по заданному смещению, и close (),
, чтобы закрыть файл после этого. Метод open ()
возвращает дескриптор файла, представляющий файловый объект, который будет использоваться для доступа к файлу для чтения, записи или добавления.
Для записи в файл необходимо принять несколько решений - имя файла, в котором будут храниться данные, и режим доступа к файлу. Доступны два режима: запись в новый файл (и перезапись любых существующих данных) и добавление данных в конец уже существующего файла. Соответствующие сокращения - «w» и «a», и их необходимо указать перед открытием файла.
В этой статье мы объясним, как записывать данные в файл построчно, как список строк и как добавлять данные в конец файла.
Запись одной строки в файл
Этот первый пример очень похож на запись в файлы с помощью популярных языков программирования C и C ++, как вы увидите в листинге 1 . Процесс довольно прост. Сначала мы открываем файл с помощью метода open ()
для записи, записываем одну строку текста в файл с помощью метода write ()
, а затем закрываем файл с помощью метода close ()
. Имейте в виду, что из-за того, как мы открыли файл helloworld.txt "он либо будет создан, если он еще не существует, либо будет полностью перезаписан.
дескриптор файла = open ('helloworld.txt', 'w')
filehandle.write ('Привет, мир! \ n')
filehandle.close ()
Листинг 1
Весь этот процесс можно сократить с помощью оператора with
. В листинге 2 показано, как это записать. Как уже было сказано ранее, имейте в виду, что при открытии файла "helloworld.txt" таким образом либо создается, если он еще не существует, либо он полностью перезаписывается, в противном случае.
с open ('helloworld.txt', 'w') в качестве дескриптора файла:
filehandle.write ('Привет, мир! \ n')
Листинг 2
Запись списка строк в файл
На самом деле файл состоит не только из одной строки, но и из гораздо большего количества данных. Таким образом, содержимое файла хранится в списке, представляющем файловый буфер. Для записи всего файлового буфера мы воспользуемся методом Writelines ()
. Листинг 3 дает вам пример этого.
filehandle = open ("helloworld.txt", "w")
filebuffer = [«первая строка текста», «вторая строка текста», «третья строка»]
filehandle.writelines (файловый буфер)
filehandle.close ()
Листинг 3
Запустив программу Python, показанную в листинге 3 , а затем используя команду cat
, мы видим, что файл helloworld.txt имеет следующее содержимое:
$ cat helloworld.txt
первая строка текста вторая строка текста третья строка
Листинг 4
Это происходит потому, что метод writelines ()
не добавляет автоматически разделители строк при записи данных. В листинге 5 показано, как этого добиться, записывая каждую строку текста в одну строку, добавляя разделитель строк "\ n". Используя выражение генератора, каждая строка заменяется разделителем «строка плюс строка». Опять же, вы можете сформулировать это, используя с оператором
.
с open ('helloworld.txt', 'w') в качестве дескриптора файла:
filebuffer = ["строка текста", "другая строка текста", "третья строка"]
filehandle.writelines ("% s \ n"% строка для строки в файловом буфере)
Листинг 5
Теперь выходной файл helloworld.txt "имеет желаемое содержимое, как показано в листинге 6 :
$ cat helloworld.txt
первая строка текста
вторая строка текста
третья линия
Листинг 6
Интересно, что в Python есть способ использовать перенаправление вывода для записи данных в файлы. Листинг 7 показывает, как это кодировать для Python 2.x.
# определяем имя выходного файла
filename = "helloworld.txt"
# определить контент
filecontent = ["Привет, мир", "вторая строка" и "третья строка"]
с open (filename, 'w') в качестве дескриптора файла:
# перенаправляем вывод print на дескриптор файла
для строки в содержании файла:
печать >> дескриптор файла, строка
Листинг 7
Для последних выпусков Python это больше не работает таким же образом.Чтобы сделать что-то подобное, мы должны использовать модуль sys
. Это позволяет нам получить доступ к стандартным каналам вывода UNIX через sys.stdout
, sys.stdin
и sys.stderr
. В нашем случае мы сохраняем исходное значение выходного канала sys.stdout
, сначала (строка 8 в коде ниже), переопределяем его на дескриптор нашего выходного файла, затем (строка 15), распечатываем данные как обычно ( строка 18) и, наконец, восстановить исходное значение выходного канала sys.stdout
(строка 21). Листинг 8 содержит пример кода.
# import sys module
import sys
# определяем имя выходного файла
filename = "helloworld.txt"
# сохранить канал стандартного вывода
оригинал = sys.stdout
# определить контент
filecontent = ["Привет, мир", "вторая строка" и "третья строка"]
с open (filename, 'w') в качестве дескриптора файла:
# установить новый выходной канал
sys.stdout = дескриптор файла
для строки в содержании файла:
печать (строка)
# восстанавливаем старый выходной канал
sys.stdout = оригинал
Листинг 8
Это не обязательно лучший метод, но он дает вам другие возможности для записи строк в файл.
Добавление данных в файл
До сих пор мы сохранили данные в новых файлах или в перезаписанных данных в существующих файлах. Но что, если мы хотим добавить данные в конец существующего файла? В этом случае нам нужно будет открыть существующий файл, используя другой режим доступа. Мы меняем его на «a» вместо «w». В листинге 9 показано, как с этим справиться. И , листинг 10, делает то же самое, но скорее использует с оператором
.
filehandle = open ('helloworld.txt', 'а')
filehandle.write ('\ n' + 'Привет, мир! \ n')
filehandle.close ()
Листинг 9
с open ('helloworld.txt', 'a') в качестве дескриптора файла:
filehandle.write ('\ n' + 'Привет, мир! \ n')
Листинг 10
Использование того же helloworld.txt из предыдущего, запуск этого кода приведет к следующему содержимому файла:
$ cat helloworld.txt
Привет мир
вторая линия
и третья строка
Привет мир!
Заключение
Запись данных в виде обычного текста в файлы или добавление данных к существующим файлам в Python так же просто, как чтение из файлов. Как только файл закрывается после записи или добавления данных, Python запускает вызов синхронизации.