Принцип EAFP в Python, работа с исключениями в Python. Применение принципов Zen of Python
Мой курс «Хардкорная веб-разработка» - 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...
Пікірлер: 196
Наверное самый полезный канал по пайтону на русскоязычном ютубе
@t0digital
3 жыл бұрын
Спасибооо!
@user-oi1zl6de8i
3 жыл бұрын
Ещё Олег Молчанов неплохо объяснял (давно у него роликов не было). И автор этого канала, на котором мы сейчас, безусловно - молодец!
@kalik54
3 жыл бұрын
@@user-oi1zl6de8i Да, как раз когда писал, Олег был на уме как и диджитализируй)
@user-oi1zl6de8i
3 жыл бұрын
@@kalik54 Да, эти товарищи вносят существенный вклад в развитие python-сообщества в России и русскоговорящих странах.
@govdamikhaylo4183
3 жыл бұрын
@@user-oi1zl6de8i +. скорее он бы вернулся(
Отличный контент. Хочется увидеть серию уроков по aiohttp, поддержите лайками чтобы поднять в топ.
@rishatsharafiev
3 жыл бұрын
starlette и fastapi интереснее
@user-zg2bx5cb3d
3 жыл бұрын
@@rishatsharafiev aiohttp и asyncio интереснее
@Uni-Coder
3 жыл бұрын
@@rishatsharafiev Асинхрон - концепт современного кодинга, это прям надо. Это есть в C++, C#, Python, Rust и вообще везде (правда, Java немного страдает), это надо изучать не только питоноидам.
@MegaFeel1
3 жыл бұрын
А мне бы Sanic, сколько людей столько мнений))
@cashncarry8
3 жыл бұрын
@@MegaFeel1 хорошо, что фреймворков меньше))
Спасибо за контент Алексей. Мне нравится, что вы уделяете внимание картинке и звуку. Предлагаю снять ролик о том, как дебажить на пайчарме. Было бы интересно.
Можно ли еще видео как до этого было, часовое по django, очень зашел формат, только по django REST)
классно, что говоришь быстро, не нужно ускорять видео)))
Алексей, спасибо большое за вашу работу. Просто и понятно!
Приятно слушать, смотреть и учиться. И все без воды. Спасибо!
Шикарный выпуск. Такие ньюансы очень полезны. Даёшь больше best practice примеров из Python и Django!
Продвигаем годноту в массы
Спасибо! Как всегда отличная подача и полезная информация!
Лайк однозначно! Качество контента растёт на глазах!
Лаконично и доступно! Пять балов за изложение мысли!
Добрый Комент!
Как всегда отличное и полезное объяснение по делу! Спасибо!
Спасибо за выпуск. Хорошо прояснил официальные подходы !) Круто!
Алексей, круто! Спасибо большое) Очень бы хотелось побольше подобных видео о лучших практиках
Спасибо ,как всегда огонь инфа!
суперская подача инфы, больше видео как надо и как не надо !)))
Очень полезное видео! Спасибо!
В первом примере LBYL подхода, должен быть еще else с выводом текста об не найденном ключе))
блин, это один из лучших каналов по программированию, от души за все советы))
@t0digital
2 жыл бұрын
спасибооо!
Неоднократно задавался вопросом, использовать условия или исключения. А, оказывается, все так просто. Теперь смогу сделать свой код лучше. Благодарю.
Очень давно так делаю, теперь просто знаю как это называется ))) Спасибо за контент!
серьезно, такая мелочь, но очень полезная инфа, оказывается данные подходы еще и именуются как-то, сколько раз с другими программистами спорили как правильно, как нет (не только питон), теперь же все по полочкам, спасибо за действительно полезный ролик, развития каналу
Было очень полезно! Спасибо!
Хороший ролик, спасибо :)
Пару дней назад нашел ваш канал и уже пересмотрел больше половины видео. Рассказывает обо всем очень доступно и интересно! Из тех, что попадались на русском KZread, наверно, первый канал, который не рассчитан на абсолютно начинающих и не рассказывает, как "Выучить Python за час" или что-то из этой серии. Удачи в развитии!
Я тоже за подход, что легче просить прощения, чем разрешение. Спасибо за прекрасный материал.
офигенное видео, спасибо!
Спасибо мужик! У тебя много что узнаю. Только уважение к тебе.
@t0digital
3 жыл бұрын
Спасибо!
Спасибо за Python контент!
@t0digital
3 жыл бұрын
Рад, что полезно:)
Спасибо за контент! Нужно скинуть в чаи группы, им должно понравиться)
"Да прибудет с вами сила" - это уже устраешая фраза. Надо говорить: "Таков путь!" ;) Спасибо за кусочек питонячей дисциплины.
Просто и грамотно. Пасиб
Вообще, слышал такое мнение: если знаешь что может пойти не так - используй if-else, так как исключение в питоне довольно медленные. Сами же исключения используются для исключительных ситуаций, когда что то идет не так из за внешних факторов. То есть в примере с диктом я бы использовал if else, в случае сетевого взаимодействия или дискового - уже исключения.
@SourPassionParty
Жыл бұрын
Да чем всех dict.get( ) не устраивает?
Спасибо! Лайк! От других программистов слышал обратное, try/except использовать если по-другому нельзя, т.к. дорогая операция. Хотя тесты которые я видел показывали, что дорогой становится при частой ловле исключений.
@t0digital
3 жыл бұрын
Try/except дешёвый, если не генерится исключение, а генериться оно должно редко, это ведь исключительная ситуация
Отличный контент. Круто прогрессировал последнее время
@t0digital
3 жыл бұрын
Спасибо! А что бы вы отметили, что за последнее время стало лучше на ваш взгяд? Темы видео, подача, картинка, звук, ещё что-то? Полезно будет знать. Спасибо!
Полезное видео. Больше подобных)
@t0digital
3 жыл бұрын
Спасибо!
Огонь! Полностью согласен!!!
Круто снял!
Спасибо за годноту, а когда будут выпуски про aiohttp?
@t0digital
3 жыл бұрын
Скоро будут!
Круто и очень полезно! Дьявол скрывается в деталях)
@t0digital
3 жыл бұрын
100%!
Спасибо, лайк!
Как интересно, а я всеми силами старался избежать try except, приму к сведению, спасибо.
@user-rs5zq9hy4m
3 жыл бұрын
Я так же)
@MA-channel1
3 жыл бұрын
Оно тоже затуманивает логику как и if на каждом шагу. Если except на каждом шагу то это не лучше а даже медленнее А если не на каждом шагу проверка нужна то можно и без if'а, и без локальных except (только большой "всё-ловящий" try/except)
Спасибо! Как раз вот пишу код и думаю об этом. Очень кстати! Было бы супер как-нибудь поглядеть на код модульных тестов, которые в том числе проверяют такие ветки с прерываниями, чтобы велосипед не изобретать.
Отлично рассказываете! У вас есть видео об ООП в python? Если нет, то было бы круто от вас услышать базовые вещи об этом! Спасибо за ваш труд!
Классный формат, рассказывать про такие маленькие фичи. И понимание зена возрастает, и код лучше будет
Блин, почти не использовал try/except в своем коде, везде пихал if/else. А после этого видео, буду писать правильно. Спасибо!!!
Спасибо!
Круто!
Полезная инфа
Обожаю свои программы заворачивать снизу доверху в except Exception! Правда я обычно пишу сервероподобный софт, а такие вещи делаю, чтобы весь процесс не упал из-за пропущёной запятой в тридевятой вьюхе.
Злой комментарий))) Спасибо за видео!
Хотел спросить. Будут ли видео по Flask? На мой взгляд это очень показательный фреймворк, т.к. есть большая свобода действия.
God bless you!
Пасиб)
А я вместо кучи ифов пользуюсь свичкейзом через метод словаря .get(key, default=None). Получается очень красиво и читаемо! Хороший ролик, лайк!
@t0digital
3 жыл бұрын
Дааа, .get очень удобный метод, тоже часто использую! Спасибо!
В защиту LBYL скажу, что сейчас в python есть довольно много инструментов, с помощью которых можно делать подобные проверки красиво и прозрачно. К примеру, библиотека trafaret. Всегда её использую при обработке тела запроса клиента на сервер.
А что насчет скорости выполнений? Читал, что try/except выполняются медленнее, чем условия, поэтому в своём коде обычно их не использую.
@ievgenk.8991
3 жыл бұрын
@@avazart614 и не про чистоту кода, по всей видимости
Добрый коммент=)
@t0digital
3 жыл бұрын
спасибо:)
Отличное видео! Алексей, когда же будет запуск обучения?
@t0digital
3 жыл бұрын
Скоро-скоро!
Огромное спасибо за видео, хоть пока мне и без толку данная информация (не тот уровень скила), но прям от видео веет дружеским наставничеством. Было бы кстати неплохо посмотреть ваш подход к началу проекта, с чего стоит начинать писать. P.S. А mailto:mailto: так и не исправили :-)
Есть мнение, что содержимое try выполняется 2 раза. 1й раз на пробу брода, 2й раз на переход брода. Поэтому если много проходов по траю - будет растрата ресурсов
Все в видео очень лаконично и ясно, будто хороший код на питоне. :) Вопрос, почему часто читаю в книгах по computer science, что использование исключений является не очень хорошей практикой программирования? И даже при создании своего языка Goland авторы, например, решили отказаться от поддержки исключений. Чем это вызвано?
@ievgenk.8991
3 жыл бұрын
Потому что исключения начинают использоваться не по назначению, они разворачивают стек вызовов и добавляют оверхед по производительности и потребляемой памяти только ради того, что бы программисты смогли снова вернуться во времена оператора goto. Исключения добавляют неясности в кодоввю базу и надо усердно курить мануалы что бы понять может ли какая то функция прокинуть ошибкуи и в каких ситуациях
Ээээ...круто)
С меня предоставляется коммент за годный контент! Жаль, что задонатить не могу(
Было бы интересно от вас послушать как SOLID применяются в Python. Думаю тема достаточно непростая и очень важная!
@kalik54
3 жыл бұрын
github.com/heykarimoff/solid.python
А че) очень полезно)
Анонсируйте подалуйста примерную дату курсов
Что там по курсу??
Очень, очень не нравятся блоки try except в коде. Единственный момент, когда могу пойти на компромисс - это интеграции - различные запросы. Но при возможности, закидал бы камнями разрабов в момент разработки либ, методы которых бросают исключения (привет request timeout error). Мало того, что сами блоки занимают много места и делают код менее читабельным, так некоторые просто напишут "except: pass" и спят спокойно. Да и в целом... все ошибки не переловишь и этот домик из "except ...: ..." может расти и расти. И это одна из причин, почему перехожу потихоньку на Golang и пишу не dictionary[key], а dictionary.get(key) и обрабатываю None. С файлом пример понравился, но будем надеиться, что, во время работы с ним одного потока, другой не делает критических изменений с флогом "w+".
В примере не совсем понятно, какое требование стоит в ТЗ. Т.к. в зависимости от этого может быть и If лучше, если ключа у нас действительно может не быть в словаре. Почему-то вы изначально за аксиому взяли, что нормальное поведение - это когда ключ есть. А если это не так? То нормальным будет уже if... Да и к тому же пример с if не полон, если добавить туда else с выводом той же ошибки, то разница уже не так очевидна. И почему во втором примере нельзя написать так? try: with open(tmp_file) as f: print(f.read()) except IOError as e: print("Error")
@ievgenk.8991
3 жыл бұрын
наверно что бы можно было понять где падает open а где read. Но это как то нелепо описывать условную логику через эксепшены.
я, в последнее время перешел 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, что бы это не значило :).
@MrPavelFrolov
3 жыл бұрын
@Вячеслав Украинцев так и есть. Поэтому они не про вадидацию. Но тут сторонняя библиотека, ну и асерты, прямо по назначению, я что-то и не использовал никогда.
Хороший Рол вкусный! Хорошо зашёл) Кто такие Катаны? «здорова Катаны»
@drdeepdreamer7090
3 жыл бұрын
Думаю, что имеется в виду кОтаны. Ну т.е. мальчики выросшие из котяток... 😃
Когда будет урок про git? В первых видео обещали, но так и не разобрали данную тему :( Сейчас на работе пришлось самому разбираться. Очень жалею что не юзал это раньше.
@t0digital
3 жыл бұрын
Я писал в 2013м статью по базовому гиту - goloburdin.blogspot.com/2013/11/git-bitbucket-20.html Видео тоже планирую, просто хочется сделать что-то глубже, чем просто commit/pull/push/merge/checkout
@MrBytmin
3 жыл бұрын
Как вас вообще на работу взяли)
не знаю что написать но напишу)
try/except вызывает отдельный стек Python в блоке try , по этому он будет медленнее. По этому с точки зрения языка вызов if 'key' in dict будет быстрее. if 'key' in dict и dict["key"] не вызывает два раза поиск ключа, а один раз, так как в стеке индекса он будет первый и пайтон всего лишь сравнит тот ли ключ.
@t0digital
3 жыл бұрын
Исключения не медленнее if/else. Исключение медленнее только если оно происходит, но оно должно происходить редко, что следует даже из названия, исключение создано для исключительных ситуаций. docs.python.org/3/faq/design.html#how-fast-are-exceptions
@kostyaten
3 жыл бұрын
@@t0digital Да глянул исходники для try если ключ проверяют вызывают _PyObject_GetDictPtr , для OS ещё не придумали как сделать try быстрее.
@kostyaten
3 жыл бұрын
@@t0digital Ещё работает для Tuple
Последний фрагмент кода нужно было написать так, чтобы *try-except* был внутри функции?
@t0digital
3 жыл бұрын
try: something = some_dict["key"] except KeyError: # do some stuff pass else: some_func(something) Напр, так
Не является ли в случае со словарями использование метода get более предпочтительным вариантом получения значения по ключу? Или этот метод по сути и есть отображение EAFP?
@t0digital
3 жыл бұрын
если задача просто получить значение по ключу, а если ключа такого в словаре нет, то взять некоторое дефолтное значение - то да, метод get предпочтительнее. EAFP он не только про словари, это общий принцип, просто на словарях его часто показывают. В видео есть пример с открытием файла и возможным состоянием гонки без EAFP
@onio2942
3 жыл бұрын
@@t0digital Спасибо за ответ! :)
4:56 у вас при исключении файл не закроется. И кстати конструкция with закрывает файл после действий, но здесь это не поможет.
А я думал, что try/except как раз для того, чтобы минимизировать ветвления и обработчики исключений, оставив один обработчик по умолчанию на самом верхнем уровне.
Да, но только конструкция try except потребляет больше ресурсов чем if, python для блока try копируются все переменные и уже с копиями выполняются операции из блока try чтобы не запороть основной цикл программы и не испортить переменные если код в try свалиться в исключение и продеться откатывать
добрый комментарий добрый комментарий добрый комментарий
@t0digital
3 жыл бұрын
Хахаах, спасибооо!
А точно стоит ронять весь код ради ключа/файла? В логи записать ERROR недостаточно будет?
@t0digital
3 жыл бұрын
Ронять весь код не надо, если это не фатальная проблема, с которой невозможно продолжать. Обработка исключений и eafp и позволяет не убивать программу.
Денис Борисов от software enginering
@t0digital
3 жыл бұрын
почему?
я так и не понял объясните еще раз- нужно всегда проверять есть ли ключ в структуре данных и потом его применять?
@t0digital
3 жыл бұрын
Всегда не надо, надо, когда есть вероятность, что ключа нет в словаре. Когда что-то может пойти не так в программе, на это надо заложиться
@doomymax577
3 жыл бұрын
@@t0digital вот на фронтэнде так всегда приходится делать потому сервера часто падают и поэтому в большинстве случаев так приходится делать
Злой писать не охота, а вот добрый, пожалуй, оставлю. У меня такая проблема. Год назад начал изучать Питона вообще с нуля. С такого уровня, что вообще первый раз открыл cmd. Сейчас пишу программы для своего бизнеса, но у меня нет развития, потому что имеющиеся знания покрывают потребности моего дела. Я понимаю, что с таким уровнем ни в какую компанию не попадёшь, а хотелось бы связать себя с профессией программиста. Прямо беда. Хочу развиваться, но вместо этого бег на месте.
Вроде сишники (особенно эмбеддщики) говорят, что исключения какие-то дорогие и слишком медленные из-за того, что там какие-то манипуляции со стэком происходят. Это правда?
Я не спрошу "что такое принцип EAFP", я спрошу "кто такие котаны или катаны"
@cashncarry8
3 жыл бұрын
Те кто отключают интернет во время деплоя))
А почему нет блока else, он нужен чтобы сообщить что ключа нет! )
4:44 а разве не лучше считывать тоже в блоке try? Вдруг во время чтения что-то произойдёт. А, точно после открытия файла для чтения файл полностью принадлежит процессу и ошибки быть не может... поэтому покрасивше будет выделить чтение в блок else
А в плане ресурсов что дешевле if или try/except? Что-то мне подсказывает, что первая конструкция...
@t0digital
3 жыл бұрын
try/except плюс-минус такой же дешевый, как и if, если не возбуждается исключение. Когда оно возбуждается - это дороже, чем if. Но соль в том, что исключение оно на то и исключение, что должно возбуждаться редко.
@Markisi0
3 жыл бұрын
@@t0digital Спасибо за ответ!
А если обернуть весь код блоком трай/эксепт, чисто в целях отлова неожиданных ошибок?
@MA-channel1
3 жыл бұрын
Можно. Только получите эту неожиданную ошибку и надо неожиданно с ней разбираться. Тут искусственные примеры были и в реальности все сложнее. И проще. Нет одного такого EAFP на всем случаи жизни. if конечно лучше, но просто не всегда надо или придется этот if включать
Аригато козаимасу:)
1. try except сложнее чем использование if key in, в читабельности для человека, из за количества возможных отрицательных срабатываний, которые спрятаны в исключениях. И if является более явным и однозначно трактуемым, нежели exception. 2. Исключения крайне ресурсоемки, и программирование на них, если можно обойтись без них, это табу. В процессе, появления исключения, в питоне собирается информация о нем, что требует много ресурсов, и останавливает поток исполнения. Такие места можно заддосить. 3. Ошибки лучше оформлять if key not in data: raise Exception('исчерпывающее описание данной ситуации') нежели то что вы привели в пример. Ваш пример можно часами трактовать, а какую ситуация для чего разраб покрыл этим exception.
@t0digital
3 жыл бұрын
Исключение такие же дешёвые, как if, если не возникает исключения, а возникать они должны редко исходя даже из названия. Что if более читаем, чем except - нет же. В исключении явно понятно, какая логика нормальна, какая исключительна, в if else обе ветки равнозначны и без контекста, без коментов это непонятно. Райзить Exception вместо KeyError или IndexError - не надо.
@user-gn8jo3zd8y
3 жыл бұрын
@@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.
Зачем вы сделали бейсбольный мячик своим крестражем?
Но исключения - это очень дорогое удовольствие, их стоит-таки избегать, если это возможно.
@dmytrokorbanytskyi1586
3 жыл бұрын
в чем дороговизна, поясните плз.
@user-ht3yt6yb9k
3 жыл бұрын
нет никакой дороговизны, по крайней мере в случае CPython. stackoverflow.com/questions/2522005/cost-of-exception-handlers-in-python docs.python.org/3/faq/design.html#how-fast-are-exceptions
@dmytrokorbanytskyi1586
3 жыл бұрын
@@user-ht3yt6yb9k абсолютно согласен с вами. На первое место в питоне надо ставить читабельность и простоту кода.
Как можно сравнивать разный функционал? Если вместо каждого if использовать try except то не только сложно будет читать, но и выполняться такая программа будет намного дольше.
@t0digital
Жыл бұрын
Так и не предлагается везде заменить if на try/except
а может лучше написать так ? if 'key' not in some_dick: continue или return или rise Exception print(some_dict['key'])
@TheNechXD
3 жыл бұрын
В случае со словарем проще воспользоваться методом get: dict_instance.get("key", "default value")
@user-jp2zc3lo9o
3 жыл бұрын
@@TheNechXD С одной стороны да, но ведь работа с дефолтным значением концептуально отличается от работы с запрашиваемым значением. Поэтому, скорее всего, дальше все равно придется ветвить "программный поток" и обрабатывать дефолтное значение отдельно. Хотя, признаю, иногда полезно использовать дефолт, например, если дальше по программе оно уже обрабатывается
@user-nj1bh7zs7d
3 жыл бұрын
@@TheNechXD а если мне не нужно дефолтное значение? Смысл вопроса в действиях если ключа нет, а не в том, что мы получаем.
@TheNechXD
3 жыл бұрын
@@user-nj1bh7zs7d При вашем подходе вы также 2 раза проверяете наличие ключа в словаре. Читабельней ли это выглядит? Спорно. Неплохое решение предлагает Java с встроенными в Optional монадами. Ваш подход решает, например, проблему вложенных if'ов (если бы они были и вы сразу бы обрезали ветвь, классический пример), но концептуально не решает поставленную задачу лучше.
@user-nj1bh7zs7d
3 жыл бұрын
@@TheNechXD не понял почему 2 раза проверяю. С Java не знаком, но знаком с C#, там есть что-то подобное (Optional монады)?