Принцип EAFP в Python, работа с исключениями в Python. Применение принципов Zen of Python
Vložit
- čas přidán 21. 08. 2020
- Мой курс «Хардкорная веб-разработка» - course.to.digital
Книжный клуб Ботаним!, где мы читаем хорошие ИТ-книги: botanim.to.digital/
Telegram: t0digital.t.me
Сказать спасибо за это видео можно здесь - boosty.to/digitalize.team
EAFP - важный принцип, позволяющий писать более «pythonic» код. EAFP расшифровывается как Easier to ask for forgiveness than permission, а его антипод LBYL - Look before you leap. Поговорим о разнице и о том, почему именно EAFP выбран разработчиками Python как правильный способ проектирования приложений.
/****************** about ******************/
Меня зовут Алексей Голобурдин, я программирую с 2004 года и на этом канале делюсь своим опытом. Я основатель и руководитель компаний:
- Диджитализируй digitalize.team, разрабатываем сложные IT системы для бизнеса;
- Salesbeat salesbeat.pro, комплексный модуль доставки для интернет магазинов.
Если у вас есть проект на разработку, пишите нам на hi@digitalize.team.
С другими предложениями, а также если вам нужна одна или несколько индивидуальных консультаций/уроков по разработке (3000 руб/час), пишите мне на alexey@salesbeat.pro.
Telegram канал - t.me/t0digital
ВК - digitalize.team
RuTube - rutube.ru/channel/24802975/ab...
Дзен - dzen.ru/id/6235d32cb64df01e6e...
Отличный контент. Хочется увидеть серию уроков по aiohttp, поддержите лайками чтобы поднять в топ.
starlette и fastapi интереснее
@@rishatsharafiev aiohttp и asyncio интереснее
@@rishatsharafiev Асинхрон - концепт современного кодинга, это прям надо. Это есть в C++, C#, Python, Rust и вообще везде (правда, Java немного страдает), это надо изучать не только питоноидам.
А мне бы Sanic, сколько людей столько мнений))
@@MegaFeel1 хорошо, что фреймворков меньше))
Наверное самый полезный канал по пайтону на русскоязычном ютубе
Спасибооо!
Ещё Олег Молчанов неплохо объяснял (давно у него роликов не было). И автор этого канала, на котором мы сейчас, безусловно - молодец!
@@user-oi1zl6de8i Да, как раз когда писал, Олег был на уме как и диджитализируй)
@@kalik54 Да, эти товарищи вносят существенный вклад в развитие python-сообщества в России и русскоговорящих странах.
@@user-oi1zl6de8i +. скорее он бы вернулся(
классно, что говоришь быстро, не нужно ускорять видео)))
Спасибо за контент Алексей. Мне нравится, что вы уделяете внимание картинке и звуку.
Предлагаю снять ролик о том, как дебажить на пайчарме. Было бы интересно.
блин, это один из лучших каналов по программированию, от души за все советы))
спасибооо!
Спасибо! Лайк! От других программистов слышал обратное, try/except использовать если по-другому нельзя, т.к. дорогая операция. Хотя тесты которые я видел показывали, что дорогой становится при частой ловле исключений.
Try/except дешёвый, если не генерится исключение, а генериться оно должно редко, это ведь исключительная ситуация
Шикарный выпуск. Такие ньюансы очень полезны. Даёшь больше best practice примеров из Python и Django!
Алексей, спасибо большое за вашу работу.
Просто и понятно!
Приятно слушать, смотреть и учиться. И все без воды. Спасибо!
Лайк однозначно! Качество контента растёт на глазах!
Спасибо! Как всегда отличная подача и полезная информация!
Продвигаем годноту в массы
Лаконично и доступно! Пять балов за изложение мысли!
Как всегда отличное и полезное объяснение по делу! Спасибо!
Алексей, круто! Спасибо большое) Очень бы хотелось побольше подобных видео о лучших практиках
Пару дней назад нашел ваш канал и уже пересмотрел больше половины видео. Рассказывает обо всем очень доступно и интересно! Из тех, что попадались на русском CZcams, наверно, первый канал, который не рассчитан на абсолютно начинающих и не рассказывает, как "Выучить Python за час" или что-то из этой серии. Удачи в развитии!
Спасибо за выпуск. Хорошо прояснил официальные подходы !) Круто!
Спасибо ,как всегда огонь инфа!
Можно ли еще видео как до этого было, часовое по django, очень зашел формат, только по django REST)
суперская подача инфы, больше видео как надо и как не надо !)))
серьезно, такая мелочь, но очень полезная инфа, оказывается данные подходы еще и именуются как-то, сколько раз с другими программистами спорили как правильно, как нет (не только питон), теперь же все по полочкам, спасибо за действительно полезный ролик, развития каналу
Хороший ролик, спасибо :)
Неоднократно задавался вопросом, использовать условия или исключения. А, оказывается, все так просто. Теперь смогу сделать свой код лучше. Благодарю.
Очень полезное видео! Спасибо!
Очень давно так делаю, теперь просто знаю как это называется )))
Спасибо за контент!
Было очень полезно! Спасибо!
офигенное видео, спасибо!
Спасибо мужик!
У тебя много что узнаю. Только уважение к тебе.
Спасибо!
Добрый Комент!
Я тоже за подход, что легче просить прощения, чем разрешение. Спасибо за прекрасный материал.
Круто снял!
Просто и грамотно. Пасиб
Спасибо за контент! Нужно скинуть в чаи группы, им должно понравиться)
Круто и очень полезно! Дьявол скрывается в деталях)
100%!
В первом примере LBYL подхода, должен быть еще else с выводом текста об не найденном ключе))
Полезное видео. Больше подобных)
Спасибо!
Огонь! Полностью согласен!!!
Вообще, слышал такое мнение: если знаешь что может пойти не так - используй if-else, так как исключение в питоне довольно медленные. Сами же исключения используются для исключительных ситуаций, когда что то идет не так из за внешних факторов. То есть в примере с диктом я бы использовал if else, в случае сетевого взаимодействия или дискового - уже исключения.
Да чем всех dict.get( ) не устраивает?
"Да прибудет с вами сила" - это уже устраешая фраза. Надо говорить: "Таков путь!" ;)
Спасибо за кусочек питонячей дисциплины.
Спасибо, лайк!
Спасибо за Python контент!
Рад, что полезно:)
Отличный контент. Круто прогрессировал последнее время
Спасибо! А что бы вы отметили, что за последнее время стало лучше на ваш взгяд? Темы видео, подача, картинка, звук, ещё что-то? Полезно будет знать.
Спасибо!
Как интересно, а я всеми силами старался избежать try except, приму к сведению, спасибо.
Я так же)
Оно тоже затуманивает логику как и if на каждом шагу. Если except на каждом шагу то это не лучше а даже медленнее
А если не на каждом шагу проверка нужна то можно и без if'а, и без локальных except (только большой "всё-ловящий" try/except)
Круто!
Спасибо! Как раз вот пишу код и думаю об этом. Очень кстати! Было бы супер как-нибудь поглядеть на код модульных тестов, которые в том числе проверяют такие ветки с прерываниями, чтобы велосипед не изобретать.
Спасибо!
А что насчет скорости выполнений? Читал, что try/except выполняются медленнее, чем условия, поэтому в своём коде обычно их не использую.
@@avazart614 и не про чистоту кода, по всей видимости
Классный формат, рассказывать про такие маленькие фичи. И понимание зена возрастает, и код лучше будет
Отлично рассказываете! У вас есть видео об ООП в python? Если нет, то было бы круто от вас услышать базовые вещи об этом! Спасибо за ваш труд!
Спасибо за годноту, а когда будут выпуски про aiohttp?
Скоро будут!
Блин, почти не использовал try/except в своем коде, везде пихал if/else. А после этого видео, буду писать правильно. Спасибо!!!
Обожаю свои программы заворачивать снизу доверху в except Exception! Правда я обычно пишу сервероподобный софт, а такие вещи делаю, чтобы весь процесс не упал из-за пропущёной запятой в тридевятой вьюхе.
Полезная инфа
А я вместо кучи ифов пользуюсь свичкейзом через метод словаря .get(key, default=None). Получается очень красиво и читаемо!
Хороший ролик, лайк!
Дааа, .get очень удобный метод, тоже часто использую!
Спасибо!
Пасиб)
God bless you!
Огромное спасибо за видео, хоть пока мне и без толку данная информация (не тот уровень скила), но прям от видео веет дружеским наставничеством.
Было бы кстати неплохо посмотреть ваш подход к началу проекта, с чего стоит начинать писать.
P.S. А mailto:mailto: так и не исправили :-)
Все в видео очень лаконично и ясно, будто хороший код на питоне. :)
Вопрос, почему часто читаю в книгах по computer science, что использование исключений является не очень хорошей практикой программирования? И даже при создании своего языка Goland авторы, например, решили отказаться от поддержки исключений. Чем это вызвано?
Потому что исключения начинают использоваться не по назначению, они разворачивают стек вызовов и добавляют оверхед по производительности и потребляемой памяти только ради того, что бы программисты смогли снова вернуться во времена оператора goto. Исключения добавляют неясности в кодоввю базу и надо усердно курить мануалы что бы понять может ли какая то функция прокинуть ошибкуи и в каких ситуациях
В примере не совсем понятно, какое требование стоит в ТЗ. Т.к. в зависимости от этого может быть и If лучше, если ключа у нас действительно может не быть в словаре.
Почему-то вы изначально за аксиому взяли, что нормальное поведение - это когда ключ есть. А если это не так? То нормальным будет уже if...
Да и к тому же пример с if не полон, если добавить туда else с выводом той же ошибки, то разница уже не так очевидна.
И почему во втором примере нельзя написать так?
try:
with open(tmp_file) as f:
print(f.read())
except IOError as e:
print("Error")
наверно что бы можно было понять где падает open а где read. Но это как то нелепо описывать условную логику через эксепшены.
Есть мнение, что содержимое try выполняется 2 раза. 1й раз на пробу брода, 2й раз на переход брода. Поэтому если много проходов по траю - будет растрата ресурсов
Ээээ...круто)
Хотел спросить. Будут ли видео по Flask? На мой взгляд это очень показательный фреймворк, т.к. есть большая свобода действия.
Отличное видео! Алексей, когда же будет запуск обучения?
Скоро-скоро!
В защиту LBYL скажу, что сейчас в python есть довольно много инструментов, с помощью которых можно делать подобные проверки красиво и прозрачно. К примеру, библиотека trafaret. Всегда её использую при обработке тела запроса клиента на сервер.
Злой комментарий)))
Спасибо за видео!
С меня предоставляется коммент за годный контент! Жаль, что задонатить не могу(
Было бы интересно от вас послушать как SOLID применяются в Python. Думаю тема достаточно непростая и очень важная!
github.com/heykarimoff/solid.python
Добрый коммент=)
спасибо:)
Очень, очень не нравятся блоки try except в коде.
Единственный момент, когда могу пойти на компромисс - это интеграции - различные запросы. Но при возможности, закидал бы камнями разрабов в момент разработки либ, методы которых бросают исключения (привет request timeout error).
Мало того, что сами блоки занимают много места и делают код менее читабельным, так некоторые просто напишут "except: pass" и спят спокойно.
Да и в целом... все ошибки не переловишь и этот домик из "except ...: ..." может расти и расти.
И это одна из причин, почему перехожу потихоньку на Golang и пишу не dictionary[key], а dictionary.get(key) и обрабатываю None.
С файлом пример понравился, но будем надеиться, что, во время работы с ним одного потока, другой не делает критических изменений с флогом "w+".
я, в последнее время перешел assert'ы:
from assertpy import assert_that
some_dict = {}
assert_that(some_dict, 'Dictionary').contains_key('key')
AssertionError: [Dictionary] Expected to contain key , but did not.
Да, не так оптимально, да, асерты не совсем про валидацию, но, на объёмах - работает лучше, чем куча try/except, в плане качества кода, читабельности. Где нужно оптимальнее - конечно меньше валидаций.
Разработчки библиотеки сказал, что я пользуюсь defensive assertions, что бы это не значило :).
@Вячеслав Украинцев так и есть. Поэтому они не про вадидацию. Но тут сторонняя библиотека, ну и асерты, прямо по назначению, я что-то и не использовал никогда.
Хороший Рол вкусный! Хорошо зашёл) Кто такие Катаны? «здорова Катаны»
Думаю, что имеется в виду кОтаны. Ну т.е. мальчики выросшие из котяток... 😃
Когда будет урок про git? В первых видео обещали, но так и не разобрали данную тему :(
Сейчас на работе пришлось самому разбираться. Очень жалею что не юзал это раньше.
Я писал в 2013м статью по базовому гиту - goloburdin.blogspot.com/2013/11/git-bitbucket-20.html
Видео тоже планирую, просто хочется сделать что-то глубже, чем просто commit/pull/push/merge/checkout
Как вас вообще на работу взяли)
А че) очень полезно)
Да, но только конструкция try except потребляет больше ресурсов чем if, python для блока try копируются все переменные и уже с копиями выполняются операции из блока try чтобы не запороть основной цикл программы и не испортить переменные если код в try свалиться в исключение и продеться откатывать
try/except вызывает отдельный стек Python в блоке try , по этому он будет медленнее. По этому с точки зрения языка вызов if 'key' in dict будет быстрее. if 'key' in dict и dict["key"] не вызывает два раза поиск ключа, а один раз, так как в стеке индекса он будет первый и пайтон всего лишь сравнит тот ли ключ.
Исключения не медленнее if/else. Исключение медленнее только если оно происходит, но оно должно происходить редко, что следует даже из названия, исключение создано для исключительных ситуаций. docs.python.org/3/faq/design.html#how-fast-are-exceptions
@@t0digital Да глянул исходники для try если ключ проверяют вызывают _PyObject_GetDictPtr , для OS ещё не придумали как сделать try быстрее.
@@t0digital Ещё работает для Tuple
А я думал, что try/except как раз для того, чтобы минимизировать ветвления и обработчики исключений, оставив один обработчик по умолчанию на самом верхнем уровне.
Анонсируйте подалуйста примерную дату курсов
4:56 у вас при исключении файл не закроется.
И кстати конструкция with закрывает файл после действий, но здесь это не поможет.
не знаю что написать но напишу)
Злой писать не охота, а вот добрый, пожалуй, оставлю. У меня такая проблема. Год назад начал изучать Питона вообще с нуля. С такого уровня, что вообще первый раз открыл cmd. Сейчас пишу программы для своего бизнеса, но у меня нет развития, потому что имеющиеся знания покрывают потребности моего дела. Я понимаю, что с таким уровнем ни в какую компанию не попадёшь, а хотелось бы связать себя с профессией программиста. Прямо беда. Хочу развиваться, но вместо этого бег на месте.
Не является ли в случае со словарями использование метода get более предпочтительным вариантом получения значения по ключу? Или этот метод по сути и есть отображение EAFP?
если задача просто получить значение по ключу, а если ключа такого в словаре нет, то взять некоторое дефолтное значение - то да, метод get предпочтительнее. EAFP он не только про словари, это общий принцип, просто на словарях его часто показывают. В видео есть пример с открытием файла и возможным состоянием гонки без EAFP
@@t0digital Спасибо за ответ! :)
добрый комментарий
добрый комментарий
добрый комментарий
Хахаах, спасибооо!
Я не спрошу "что такое принцип EAFP", я спрошу "кто такие котаны или катаны"
Те кто отключают интернет во время деплоя))
4:44 а разве не лучше считывать тоже в блоке try? Вдруг во время чтения что-то произойдёт.
А, точно после открытия файла для чтения файл полностью принадлежит процессу и ошибки быть не может... поэтому покрасивше будет выделить чтение в блок else
А почему нет блока else, он нужен чтобы сообщить что ключа нет! )
Последний фрагмент кода нужно было написать так, чтобы *try-except* был внутри функции?
try:
something = some_dict["key"]
except KeyError:
# do some stuff
pass
else:
some_func(something)
Напр, так
А если обернуть весь код блоком трай/эксепт, чисто в целях отлова неожиданных ошибок?
Можно. Только получите эту неожиданную ошибку и надо неожиданно с ней разбираться.
Тут искусственные примеры были и в реальности все сложнее. И проще. Нет одного такого EAFP на всем случаи жизни.
if конечно лучше, но просто не всегда надо или придется этот if включать
1. try except сложнее чем использование if key in, в читабельности для человека, из за количества возможных отрицательных срабатываний, которые спрятаны в исключениях. И if является более явным и однозначно трактуемым, нежели exception.
2. Исключения крайне ресурсоемки, и программирование на них, если можно обойтись без них, это табу. В процессе, появления исключения, в питоне собирается информация о нем, что требует много ресурсов, и останавливает поток исполнения. Такие места можно заддосить.
3. Ошибки лучше оформлять
if key not in data:
raise Exception('исчерпывающее описание данной ситуации')
нежели то что вы привели в пример. Ваш пример можно часами трактовать, а какую ситуация для чего разраб покрыл этим exception.
Исключение такие же дешёвые, как if, если не возникает исключения, а возникать они должны редко исходя даже из названия. Что if более читаем, чем except - нет же. В исключении явно понятно, какая логика нормальна, какая исключительна, в if else обе ветки равнозначны и без контекста, без коментов это непонятно. Райзить Exception вместо KeyError или IndexError - не надо.
@@t0digital
1. Style
docs.python.org/3.8/faq/design.html#how-fast-are-exceptions
2. Performance
paltman.com/try-except-performance-in-python-a-simple-test/
3.
- Как в коде, который покрыт несколькими слоями try except finally, излишние try, усложняет структуру кода, доп отступами от которых не избавиться.
- Две строки, лучше чем четыре.
- Как быть здесь? На каком ключе споткнулись?
try:
value = data['key1']['key2']
except IndexError:
pass
- может все же вот так понятней?
if 'key1' not in data:
raise Exception('исчерпывающий ответ что пошло не так')
исполнение продолжилось.
- к какому жесткачу, приводит неосторожное использование.
try:
value = function()
except Exception:
pass
- трактовки.
Что можно ожидать от if key in data ?
Наверно, проверку вхождения, в массив, в строку или есть ли ключ в hashmap, зависит от типа данных data.
Что можно ожидать от try except. Очень много всего, особенно когда обернута функция, и глубину вызовов внутри этой функции не видно, и на любом этапе может произойти исключение, которое этот перехват скроет. А бывает и приведет к некорректному исполненbю алгоритма.
- нарушение логики.
С исключениями, мы предпочитаем сначала наступить в кучу навоза, а потом принимать решение. А проще, посмотреть прежде чем наступать нет ли там кучу с помощью if.
Что на итог:
Эту конструкцию, опытный разработчик назовет вкусовщиной. Я же против этих конструкций, т.к. мы не все опытные и знаем все подводные камни и отдаем себе отчет в них, и суем их всюду.
И это приводит к страшным поломкам. Чего не случится, если бы использовали if.
А в плане ресурсов что дешевле if или try/except? Что-то мне подсказывает, что первая конструкция...
try/except плюс-минус такой же дешевый, как и if, если не возбуждается исключение. Когда оно возбуждается - это дороже, чем if. Но соль в том, что исключение оно на то и исключение, что должно возбуждаться редко.
@@t0digital Спасибо за ответ!
А точно стоит ронять весь код ради ключа/файла?
В логи записать ERROR недостаточно будет?
Ронять весь код не надо, если это не фатальная проблема, с которой невозможно продолжать. Обработка исключений и eafp и позволяет не убивать программу.
я так и не понял объясните еще раз- нужно всегда проверять есть ли ключ в структуре данных и потом его применять?
Всегда не надо, надо, когда есть вероятность, что ключа нет в словаре. Когда что-то может пойти не так в программе, на это надо заложиться
@@t0digital вот на фронтэнде так всегда приходится делать потому сервера часто падают и поэтому в большинстве случаев так приходится делать
Вроде сишники (особенно эмбеддщики) говорят, что исключения какие-то дорогие и слишком медленные из-за того, что там какие-то манипуляции со стэком происходят. Это правда?
Что там по курсу??
Но исключения - это очень дорогое удовольствие, их стоит-таки избегать, если это возможно.
в чем дороговизна, поясните плз.
нет никакой дороговизны, по крайней мере в случае CPython.
stackoverflow.com/questions/2522005/cost-of-exception-handlers-in-python
docs.python.org/3/faq/design.html#how-fast-are-exceptions
@@user-ht3yt6yb9k абсолютно согласен с вами. На первое место в питоне надо ставить читабельность и простоту кода.
В 1с использование такой конструкции считается плохим тоном.
Значит программист плохо учел возможные варианты, раз у него что-то может вызвать исключение.
1C сам по себе считается плохим тоном.
P.S. Ладно, шутка
@@user-dv9fk1hd3s давай напишем систему лучше) Аналогов я не нашел, ниша свободна.
Не шутка)
Денис Борисов от software enginering
почему?
Письмо от хейтера (шутка, уважаю твой канал).
Внезапно, в Rust лучше реализованы принципы Python, чем в самом Python: и принцип "явное лучше неявного", и принцип "EAFP", а в качестве бонуса ещё и статическая типизация и всё это делается без исключений.
value = some_hashmap.get("key")? // Передача ошибки выше по стеку
value = some_hashmap.get("key").unwrap(); // Ленивый вылет из программы
value = some_hashmap.get("key").expect("Нет тут такого ключа"); // Чуть более сложный вылет
Всё в одну строку.
Ну, и говорить о преимуществе одной константной операции вместо двух... На python?.. Гм... Ну, такое
До ржавчины пока руки не дошли, но на досуге хочу познакомиться. Хотя блин кого я обманываю, какой нахрен досуг))
Аригато козаимасу:)
Как можно сравнивать разный функционал? Если вместо каждого if использовать try except то не только сложно будет читать, но и выполняться такая программа будет намного дольше.
Так и не предлагается везде заменить if на try/except