PROG_WAY_BLOG Telegram 25
Сегодня будет достаточно глубокий экскурс в Python исключения.

Для кого-то эта тема может быть очевидной, но для некоторых начинающих разработчиков эта тема всё ещё не открыта. Итак, что же такое исключения?

Действия программы, которые противоречат тем или иным правилам вызывают исключения. Например попытка поделить на ноль вызовет ZeroDivisionError, а попытка сложить строку и кортеж - TypeError.

"Отловить" ошибки можно при помощи конструкции try/except/else/finally. Например:

def division(a,b):
try:
return a/b
except ZeroDivisionError:
return None

Теперь работа программы не будет ломаться при делении на ноль, а продолжит свою работу. Но это далеко не значит, что использование блока try/except - панацея. Об этом чуть позже.

Как же создать своё исключение? Легко:

class MyOwnException(Exception):
pass

или

class MyOwnException(Exception):
# разный функционал, что выполнится при исключении

Как вы видите, для создания своего исключения мы создаём новый класс, который наследуем от базового класса Exception. Чтобы выбросить это исключение в программе мы воспользуемся оператором raise:

#  какое-то условие, что вызывает исключение
raise MyOwnException('Message')
>>> __main__.MyOwnException: Message

Замечательно, удобно для программиста, быстро но теперь поговорим о том почему это плохо:

1. Большое количество исключений - всегда сложно, запутывает и разработчиков, и пользователей.
2. Лучше предусмотреть альтернативный выход из исключительной ситуации.
3. Плохо влияет на будущую поддерживаемость и ясность вашего кода.
4. Все исключения всё равно не получится поймать.

Я уже рассказывал вам про декораторы тут, так что вот какое решение могу предложить. Оформим собственное исключение, декоратор, что сохранит любую нашу функцию и задекорируем объявленную ранее функцию division. Вашему вниманию предлагаю такой код:

from functools import wraps

class Error(Exception):

def __repr__(self):
return 'Error'

def __str__(self):
return 'Error'

def safe(func):

@wraps(func)
def wrapped(*args, **kwargs):
try:
return func(*args, **kwargs)
except:
return Error()

return wrapped

@safe # декорируем функцию
def division(a, b):
return a / b

division(4,0)
>>> Error

Итак, что тут происходит? Для начала о @wraps. Я еще не рассказывал о нём, но этот декоратор нужен для сохранения таких параметров функции как __name__ и __doc__, так как после декорирования эти параметры переписываются. Под коробкой этот декоратор на примере можно заменить вот так вот так:

def safe(func)

def wrapped(*args, **kwargs):
try:
return func(*args, **kwargs)
except:
return Error()

wrapped.__name__ = func.__name__
wrapped.__doc__ = func.__doc__

return wrapped
А теперь обо всём в целом. Мы создали декоратор safe, который позволит обезопасить любую функцию от любой ошибки. При объявлении небезопасной функции с этим декоратором мы получаем абсолютно неломаемую программу, а выглядит решение ну очень уж лаконично. Кстати, в блоке except мы можем возвращать не только наш экземпляр класса Error, но и любое другое значение, которое нам будет удобно, например float('inf'), что вернёт нам бесконечность. (Кстати, в рассмотренном примере не обязательно возвращать именно экземпляр класса. С таким же успехом можно вернуть просто строку "Error", но я оставил класс для того, чтобы вы могли легко модифицировать поведение своей ошибки)

Ну и естественно моё решение далеко не эталонно, но оно уже в разы лучше и удобнее, чем писать в каждой функции свой собственный обработчик (за редким исключением). Если вам нужно быстро обезопасить свою функцию, то это вполне себе неплохое решение.

Способов решить проблему исключений есть ещё много, а весь материал, что я изложил тут, чрезвычайно сжат. Новичкам я конечно же советую погрузиться в тему глубже. Это важнее, чем кажется.

А этот декоратор был бы неплохим началом для моей коллекции декораторов, да?)

#python



tgoop.com/prog_way_blog/25
Create:
Last Update:

Сегодня будет достаточно глубокий экскурс в Python исключения.

Для кого-то эта тема может быть очевидной, но для некоторых начинающих разработчиков эта тема всё ещё не открыта. Итак, что же такое исключения?

Действия программы, которые противоречат тем или иным правилам вызывают исключения. Например попытка поделить на ноль вызовет ZeroDivisionError, а попытка сложить строку и кортеж - TypeError.

"Отловить" ошибки можно при помощи конструкции try/except/else/finally. Например:

def division(a,b):
try:
return a/b
except ZeroDivisionError:
return None

Теперь работа программы не будет ломаться при делении на ноль, а продолжит свою работу. Но это далеко не значит, что использование блока try/except - панацея. Об этом чуть позже.

Как же создать своё исключение? Легко:

class MyOwnException(Exception):
pass

или

class MyOwnException(Exception):
# разный функционал, что выполнится при исключении

Как вы видите, для создания своего исключения мы создаём новый класс, который наследуем от базового класса Exception. Чтобы выбросить это исключение в программе мы воспользуемся оператором raise:

#  какое-то условие, что вызывает исключение
raise MyOwnException('Message')
>>> __main__.MyOwnException: Message

Замечательно, удобно для программиста, быстро но теперь поговорим о том почему это плохо:

1. Большое количество исключений - всегда сложно, запутывает и разработчиков, и пользователей.
2. Лучше предусмотреть альтернативный выход из исключительной ситуации.
3. Плохо влияет на будущую поддерживаемость и ясность вашего кода.
4. Все исключения всё равно не получится поймать.

Я уже рассказывал вам про декораторы тут, так что вот какое решение могу предложить. Оформим собственное исключение, декоратор, что сохранит любую нашу функцию и задекорируем объявленную ранее функцию division. Вашему вниманию предлагаю такой код:

from functools import wraps

class Error(Exception):

def __repr__(self):
return 'Error'

def __str__(self):
return 'Error'

def safe(func):

@wraps(func)
def wrapped(*args, **kwargs):
try:
return func(*args, **kwargs)
except:
return Error()

return wrapped

@safe # декорируем функцию
def division(a, b):
return a / b

division(4,0)
>>> Error

Итак, что тут происходит? Для начала о @wraps. Я еще не рассказывал о нём, но этот декоратор нужен для сохранения таких параметров функции как __name__ и __doc__, так как после декорирования эти параметры переписываются. Под коробкой этот декоратор на примере можно заменить вот так вот так:

def safe(func)

def wrapped(*args, **kwargs):
try:
return func(*args, **kwargs)
except:
return Error()

wrapped.__name__ = func.__name__
wrapped.__doc__ = func.__doc__

return wrapped
А теперь обо всём в целом. Мы создали декоратор safe, который позволит обезопасить любую функцию от любой ошибки. При объявлении небезопасной функции с этим декоратором мы получаем абсолютно неломаемую программу, а выглядит решение ну очень уж лаконично. Кстати, в блоке except мы можем возвращать не только наш экземпляр класса Error, но и любое другое значение, которое нам будет удобно, например float('inf'), что вернёт нам бесконечность. (Кстати, в рассмотренном примере не обязательно возвращать именно экземпляр класса. С таким же успехом можно вернуть просто строку "Error", но я оставил класс для того, чтобы вы могли легко модифицировать поведение своей ошибки)

Ну и естественно моё решение далеко не эталонно, но оно уже в разы лучше и удобнее, чем писать в каждой функции свой собственный обработчик (за редким исключением). Если вам нужно быстро обезопасить свою функцию, то это вполне себе неплохое решение.

Способов решить проблему исключений есть ещё много, а весь материал, что я изложил тут, чрезвычайно сжат. Новичкам я конечно же советую погрузиться в тему глубже. Это важнее, чем кажется.

А этот декоратор был бы неплохим началом для моей коллекции декораторов, да?)

#python

BY progway — программирование, IT




Share with your friend now:
tgoop.com/prog_way_blog/25

View MORE
Open in Telegram


Telegram News

Date: |

A few years ago, you had to use a special bot to run a poll on Telegram. Now you can easily do that yourself in two clicks. Hit the Menu icon and select “Create Poll.” Write your question and add up to 10 options. Running polls is a powerful strategy for getting feedback from your audience. If you’re considering the possibility of modifying your channel in any way, be sure to ask your subscribers’ opinions first. The channel also called on people to turn out for illegal assemblies and listed the things that participants should bring along with them, showing prior planning was in the works for riots. The messages also incited people to hurl toxic gas bombs at police and MTR stations, he added. Content is editable within two days of publishing Those being doxxed include outgoing Chief Executive Carrie Lam Cheng Yuet-ngor, Chung and police assistant commissioner Joe Chan Tung, who heads police's cyber security and technology crime bureau. 2How to set up a Telegram channel? (A step-by-step tutorial)
from us


Telegram progway — программирование, IT
FROM American