файл_об - объект файла, возвращаемый функцией open() режим - строка, указывающая на тип файла и действия, которые нужно произвести над файлом имя_файла
Первая буква строки режим указывает на операцию: r - read w - write. Если файла нет - будет создан. Если файл есть - будет перезаписан. x - write, только если такого файла еще нет, иначе выкинет FileExistsError a - add данных в конец файла, если он существует
Вторая буква строки режим указывает на тип файла: t или ничего - текстовый файл b - binary
После открытия файла нужно вызвать функции для чтения/записи. Затем нужно закрыть файл, для гарантии того, что все операции записи завершены, а память освобождена. (Впрочем, оператор with может это всё автоматизировать)
Пример создания пустого файла(открытия и закрытия файла):
write() не добавляет никаких пробелов или символов новой строки, в отличие от print():
>>> poem = '''Boys and girls, come out to play. The moon doth shine as bright as day.'''>>> len(poem)81>>> fout = open('test', 'w')>>> fout.write(poem)81 # Число записанных байтов>>> fout.close()# или:>>> print(poem, file=fout)
Запись в бинарник. write()
В этом режиме читаться/записываться будут байты, а не строки:
>>> poem = '''Boys and girls, come out to play. The moon doth shine as bright as day. The moon doth shine as bright as day. The moon doth shine as bright as day.'''>>> fout = open('test', 'w')>>> size = len(poem)>>> offset = 0>>> chunk = 100>>> while True: if offset > size: break fout.write(poem[offset:(offset+chunk)]) offset += chunk10047
Код выше первым заходом записал 100 символов, затем - 47.
Можно указать макс. кол-во символов, которое read() вернет за один вызов:
>>> poem = ''>>> fin = open('test', 'r' )>>> chunk = 100>>> while True: fragment = fin.read(chunk) if not fragment: break poem += fragment>>> fin.close()>>> len(poem)150
После того как прочитается весь файл, дальнейшие вызовы read() будут возвращать пустую строку '', которая рассматривается как False при проверке if not fragment.
Кодировка
В open() можно также передать нужную кодировку:
filiee = read('test', 'r', encoding='utf-8')
Можно считывать построчно w/ readline():
>>> poem = ''>>> fin = open('test', 'r' )>>> while True: line = fin.readline() if not line: break poem += line>>> fin.close()>>> len(poem)150
Для текстового файла даже пустая строка имеет длину (1 - символ новой строки) и такая строка будет считаться True. Когда весь файл будет считан, функция readline() (read() тоже) вернет пустую строку, которая - False.
Но всё же самый простой способ считать текстовый файл - юзать итератор, который будет возвращать по одной строке за раз. Пример ниже похож на предыдущий, но кода меньше:
>>> poem = ''>>> fin = open('test', 'r' )>>> for line in fin: poem += line>>> fin.close()>>> len(poem)150
Чтение бинарника. read()
>>> fin = open('bfile', 'rb')>>> bdata = fin.read()>>> len(bdata)256>>> fin.close()
Ключевое слово with()
Если забудешь закрыть файл, его закроет Python после того, как будет удалена последняя ссылка на этот файл. ⇒ если откроешь файл и не закроешь его явно, он будет закрыт автоматически по завершении функции. Файл должен быть закрыт, чтобы все оставшиеся операции записи были завершены.
В Python есть менеджеры контекста для очистки таких объектов, как открытые файлы:
with выражение as переменная>>> with open('relativity', 'w') as fout: fout.write(poem)
После того как блок кода, расположенный под менеджером контекста завершится (или нормально, или путем генерации исключения), файл закроется автоматически.
Смена позиции. seek() и tell()
В процессе чтения/записи Python отслеживает местоположение в файле. tell() возвращает текущее смещение от начала файла в байтах. seek() позволяет перейти к другому смещению в файле. ⇒ не обязательно прочитывать каждый байт файла, чтобы добраться до последнего.
>>> fin = open('bfile', 'rb')>>> fin.tell()0>>> fin.seek(255)255
Считывание всех данных от текущей позиции до конца файла:
>>> fin = open('bfile', 'rb')# Один байт перед концом файла:>>> fin.seek(-1, 2)255>>> fin.tell()255# Считать данные до конца файла:>>> bdata = fin.read()>>> len(bdata)1>>> bdata[0]255
Смена позиции на 2 байта до конца файла:
>>> fin.seek(254, 0)254>>> fin.tell()254# или на 1 байт:>>> fin.seek(1, 1)255>>> fin.tell()255
Эти функции наиболее полезны при работе с бинарниками.
Их можно юзать и для работы с текстовыми файлами, но если файл состоит не только из символов формата ASCII (каждый из которых занимает по 1 байту в памяти), будет трудно определить смещение. Ибо оно будет зависеть от кодировки текста, а самая популярная кодировка (UTF-8) использует разное кол-во байтов для разных символов.