Механизм исключений был подробно описан в статье «Обработка исключений«. Теперь мы посмотрим как это работает в Python. Исключения (исключительные ситуации, exceptions) являются механизмом обработки ошибок, который пришел на смену возврату кода ошибки функциями. Сейчас этот механизм применяется почти во всех языках программирования и пользоваться им надо уметь так как вырабатываются исключения функциями стандартной библиотеки, а если смотреть на Python — то вообще всем, чем можно:
a = «123» b = 2 result = a/b
При выполнении этого фрагмента получим сообщение об ошибке:
Traceback (most recent call last): File «main.py», line 3, in result = a/b TypeError: unsupported operand type(s) for /: ‘str’ and ‘int’
Исключения на уровне языка программирования существуют для того, чтобы было проще справлять с ошибками, научиться вовремя локализовать проблему и ее устранить либо вообще попытаться восстановить дальнейшую работу программу. Приведенный ниже пример демонстрирует синтаксис обработки исключений:
Пишу реальную программу. Парсинг текстового файла. Python + Pandas + Excel.
def myDiv(a, b): try: result = a/b return result except TypeError: return «type error» except ZeroDivisionError: return «zero division error» result = myDiv(«123», 2) print([«result: «, result]) result = myDiv(123, 2) print([«result: «, result]) result = myDiv(123, 0) print([«result: «, result])
Программа выдаст следующий результат:
[‘result: ‘, ‘type error’] [‘result: ‘, 61.5] [‘result: ‘, ‘zero division error’] ** Process exited — Return Code: 0 ** Press Enter to exit terminal
Тут видно, что при различных ситуациях одна и та же строка кода генерирует различные ошибки. Конструкция try. catch позволяет отлавливать их и в зависимости от типа выполнять тот или иной код. Очевидно, что в языке Python, как и в других языках, поддерживается некоторый стандартный набор исключений. Каждое исключение представляет собой класс, наследующий стандартный класс исключений. Примерно пятую часть стандартных исключений я уложил на следующую диаграмму классов:
Ясно, что программисту никогда не нужно помнить все имена классов исключений, однако надо знать что если он, например, попробует открыть несуществующий файл или записать информацию в файл, защищенный от записи — то система выработает какое-то исключение. Имя исключения всегда можно взять в документации.
Блок finally
Про него пишем отдельно, так как соответствующая синтаксическая конструкция не поддерживается в некоторых других языках программирования. Допустим, что вы выполняет чтение из файла или работаете еще с какими-то большими ресурсами. В результате обработки происходит какая-то ошибка и нужные действия не выполняются.
Но вы уже используете некоторые ресурсы, которые в любом случае нужно освобождать, в независимости от того, насколько удачно выполнены операции с ними. Файл нужно закрыть, соединение с БД нужно закрыть и т.д. Для этого в конструкцию try-except добавляется еще один компонент — блок finally. За этим ключевым словом обычно помещают те операторы, которые должны быть выполнены всегда(!), в независимости от того, было сгенерировано исключение или нет. Например так наша функция могла бы быть изменена чтобы выводить на экран сообщение о ее завершении (с целью логгирования или отладки):
#51. Функция open. Чтение данных из файла | Python для начинающих
def myDiv(a, b): try: result = a/b return result except TypeError: return «type error» except ZeroDivisionError: return «zero division error» finally: print(«myDiv finished»)
Обработка ошибок при работе с файлами
При работе с файлами также могут возникать ошибки, которые нужно обрабатывать. А после работы файл следует не забыть закрыть, чтобы освободить занятые им ресурсы. И тут нам на помощь приходит блок try-except:
try: file_obj = open(«path», ‘r’) print(file_obj.read()) except IOError: print(«I/O Error») finally: file_obj.close()
Менеджеры контекста
Смотрим на последний пример и понимаем, что тут изображена какая-то типичная конструкция, связанная с использованием ресурса. В блоке try получаем к нему доступ, а в блоке finally — возвращаем ресурс.
Так как такая конструкция встречается постоянно, для нее была добавлена более удобная форма, реализуемая с помощью так называемого, менеджера контекста. Для некоторых встроенных объектов в языке Python уже определен менеджер контекста, например, для файлов. Для использования менеджера используется синтаксис:
with [as ]:
Например, приведенный выше пример с файлами полностью эквивалентен следующему:
with open(«path», ‘r’) as file_obj: print(file_obj.read())
Источник: pro-prof.com
Чтение данных из файла и запись в файл
В Python, чтобы создать файл, надо его открыть в режиме записи ( ‘w’ , ‘wb’ ) или дозаписи ( ‘a’ , ‘ab’ ).
f2 = open(«text2.txt», ‘w’)
Функция open() возвращает файловый объект.
Без ‘b’ создается текстовый файл, представляющий собой поток символов. С ‘b’ — файл, содержащий поток байтов.
В Python также существует режим ‘x’ или ‘xb’ . В этом режиме проверяется, есть ли файл. Если файл с определенным именем уже существует, он не будет создан. В режиме ‘w’ файл создается заново, старый при этом теряется.
>>> f1 = open(‘text1.txt’, ‘w’) >>> f2 = open(‘text1.txt’, ‘x’) Traceback (most recent call last): File «», line 1, in FileExistsError: [Errno 17] File exists: ‘text1.txt’ >>> f3 = open(‘text1.txt’, ‘w’)
Чтение данных из файла
Если в функцию open() не передается второй аргумент, файл расценивается как текстовый и открывается на чтение.
Попытка открыть на чтение несуществующий файл вызывает ошибку.
>>> f = open(«text10.txt») Traceback (most recent call last): File «», line 1, in IOError: [Errno 2] No such file or directory: ‘text10.txt’
Перехватить возникшее исключение можно с помощью конструкции try-except .
>>> try: . f = open(«text10.txt») . except IOError: . print («No file») . No file
Получить все данные из файла можно с помощью метода read() файлового объекта, предварительно открыв файл на чтение. При этом файловый объект изменяется и получить из него данные еще раз не получится.
>>> f = open(«text.txt») >>> f >>> fd = f.read() >>> fd1 = f.read() >>> fd ‘HellontOnen TwonThree FournШесть!n’ >>> fd1 »
Методу read() может быть передан один аргумент, обозначающий количество байт для чтения.
>>> f = open(«text.txt») >>> fd = f.read(10) >>> fd1 = f.read(5) >>> fd ‘HellontOne’ >>> fd1 ‘n T’
Метод readline() позволяет получать данные построчно.
>>> f = open(«text.txt») >>> f.readline() ‘Hellon’ >>> f.readline() ‘tOnen’ >>> f.readline() ‘ Twon’
Принимает аргумент — число байт.
>>> f.readline(3) ‘Thr’ >>> f.readline(3) ‘ee ‘ >>> f.readline(3) ‘Fou’ >>> f.readline(3) ‘rn’ >>> f.readline(5) ‘Шесть’ >>> f.readline(5) ‘!n’
Метод readlines() считывает все строки и помещает их в список.
>>> f = open(«text.txt») >>> fd = f.readlines() >>> fd [‘Hellon’, ‘tOnen’, ‘ Twon’, ‘Three Fourn’, ‘Шесть!n’]
Может принимать количество байт, но дочитывает строку до конца.
>>> f = open(«text.txt») >>> fd = f.readlines(3) >>> fd [‘Hellon’] >>> fd1 = f.readlines(6) >>> fd1 [‘tOnen’, ‘ Twon’]
Запись данных в файл
Записать данные в файл можно с помощью метода write() , который возвращает число записанных символов.
>>> f1 = open(«text1.txt», ‘w’) >>> f1.write(«Table, cup.nBig, small.») 23 >>> a = f1.write(«Table, cup.nBig, small.») >>> type(a)
Файл, открытый на запись, нельзя прочитать. Для этого требуется его закрыть, а потом открыть на чтение.
>>> f1.read() Traceback (most recent call last): File «», line 1, in io.UnsupportedOperation: not readable >>> f1.close() >>> f1 = open(«text1.txt», ‘r’) >>> f1.read() ‘Table, cup.nBig, small.Table, cup.nBig, small.’
С помощью метода writelines() можно записать в файл итерируемую последовательность.
>>> a = [1,2,3,4,5,6,7,8,9,0] >>> f = open(«text2.txt»,’w’) >>> f.writelines(«%sn» % i for i in a) >>> f.close() >>> open(«text2.txt»).read() ‘1n2n3n4n5n6n7n8n9n0n’ >>> print(open(«text2.txt»).read()) 1 2 3 4 5 6 7 8 9 0
Смена позиции в файле
>>> f = open(‘text.txt’) >>> f.read() ‘HellontOnen TwonThree FournШесть!n’ >>> f.close() >>> f = open(‘text.txt’) >>> f.seek(10) 10 >>> f.read() ‘n TwonThree FournШесть!n’
Двоичные файлы
Пример копирования изображения:
>>> f1 = open(‘flag.png’, ‘rb’) >>> f2 = open(‘flag2.png’, ‘wb’) >>> f2.write(f1.read()) 446 >>> f1.close() >>> f2.close()
Модуль struct позволяет преобразовывать данные к бинарному виду и обратно.
>>> f = open(‘text3.txt’, ‘wb’) >>> f.write(‘3’) Traceback (most recent call last): File «», line 1, in TypeError: ‘str’ does not support the buffer interface >>> d = struct.pack(‘>i’,3) >>> d b’x00x00x00x03′ >>> f.write(d) 4 >>> f.close() >>> f = open(‘text3.txt’) >>> d = f.read() >>> d ‘x00x00x00x03’ >>> struct.unpack(‘>i’,d) Traceback (most recent call last): File «», line 1, in TypeError: ‘str’ does not support the buffer interface >>> f = open(‘text3.txt’, ‘rb’) >>> d = f.read() >>> d b’x00x00x00x03′ >>> struct.unpack(‘>i’,d) (3,)
Источник: pythoner.name
Что произойдет, если открыть несуществующий файл на запись?
Если открыть несуществующий файл на запись, то файл будет создан в случае, если права доступа позволят создание файла в данном месте, и программа сможет писать в этот файл. Если права доступа не позволяют создание файла или программа не может писать в данный файл, будет выведено сообщение об ошибке и операция записи будет неудачной.
Пример кода на Python, который попытается открыть файл на запись:
try: file = open(«file.txt», «w») # операции записи в файл file.close() except OSError: print(«Не удалось открыть файл на запись»)
Если файл «file.txt» не существует, он будет создан в той же директории, где выполняется программа. Если программе не удастся создать файл или открыть его на запись, будет выведено сообщение об ошибке.
Источник: aisearch.ru