Принцип EAFP в Python, работа с исключениями в Python. Применение принципов Zen of Python
Вставка
- Опубліковано 4 жов 2024
- Мой курс «Хардкорная веб-разработка» - course.to.digital
Книжный клуб Ботаним!, где мы читаем хорошие ИТ-книги: botanim.to.dig...
Telegram: t0digital.t.me
Сказать спасибо за это видео можно здесь - boosty.to/digi...
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
ВК - digital...
RuTube - rutube.ru/chan...
Дзен - dzen.ru/id/623...
Отличный контент. Хочется увидеть серию уроков по aiohttp, поддержите лайками чтобы поднять в топ.
starlette и fastapi интереснее
@@rishatsharafiev aiohttp и asyncio интереснее
@@rishatsharafiev Асинхрон - концепт современного кодинга, это прям надо. Это есть в C++, C#, Python, Rust и вообще везде (правда, Java немного страдает), это надо изучать не только питоноидам.
А мне бы Sanic, сколько людей столько мнений))
@@MegaFeel1 хорошо, что фреймворков меньше))
Наверное самый полезный канал по пайтону на русскоязычном ютубе
Спасибооо!
Ещё Олег Молчанов неплохо объяснял (давно у него роликов не было). И автор этого канала, на котором мы сейчас, безусловно - молодец!
@@ИванИванов-н9т9ъ Да, как раз когда писал, Олег был на уме как и диджитализируй)
@@kalik54 Да, эти товарищи вносят существенный вклад в развитие python-сообщества в России и русскоговорящих странах.
@@ИванИванов-н9т9ъ +. скорее он бы вернулся(
классно, что говоришь быстро, не нужно ускорять видео)))
блин, это один из лучших каналов по программированию, от души за все советы))
спасибооо!
Спасибо за контент Алексей. Мне нравится, что вы уделяете внимание картинке и звуку.
Предлагаю снять ролик о том, как дебажить на пайчарме. Было бы интересно.
Спасибо! Лайк! От других программистов слышал обратное, try/except использовать если по-другому нельзя, т.к. дорогая операция. Хотя тесты которые я видел показывали, что дорогой становится при частой ловле исключений.
Try/except дешёвый, если не генерится исключение, а генериться оно должно редко, это ведь исключительная ситуация
Шикарный выпуск. Такие ньюансы очень полезны. Даёшь больше best practice примеров из Python и Django!
Продвигаем годноту в массы
Алексей, спасибо большое за вашу работу.
Просто и понятно!
Добрый Комент!
Приятно слушать, смотреть и учиться. И все без воды. Спасибо!
"Да прибудет с вами сила" - это уже устраешая фраза. Надо говорить: "Таков путь!" ;)
Спасибо за кусочек питонячей дисциплины.
Отличный контент. Круто прогрессировал последнее время
Спасибо! А что бы вы отметили, что за последнее время стало лучше на ваш взгяд? Темы видео, подача, картинка, звук, ещё что-то? Полезно будет знать.
Спасибо!
Лаконично и доступно! Пять балов за изложение мысли!
Спасибо за Python контент!
Рад, что полезно:)
Огонь! Полностью согласен!!!
Лайк однозначно! Качество контента растёт на глазах!
серьезно, такая мелочь, но очень полезная инфа, оказывается данные подходы еще и именуются как-то, сколько раз с другими программистами спорили как правильно, как нет (не только питон), теперь же все по полочкам, спасибо за действительно полезный ролик, развития каналу
Круто и очень полезно! Дьявол скрывается в деталях)
100%!
Пару дней назад нашел ваш канал и уже пересмотрел больше половины видео. Рассказывает обо всем очень доступно и интересно! Из тех, что попадались на русском UA-cam, наверно, первый канал, который не рассчитан на абсолютно начинающих и не рассказывает, как "Выучить Python за час" или что-то из этой серии. Удачи в развитии!
Просто и грамотно. Пасиб
Неоднократно задавался вопросом, использовать условия или исключения. А, оказывается, все так просто. Теперь смогу сделать свой код лучше. Благодарю.
Полезное видео. Больше подобных)
Спасибо!
Как интересно, а я всеми силами старался избежать try except, приму к сведению, спасибо.
Я так же)
Оно тоже затуманивает логику как и if на каждом шагу. Если except на каждом шагу то это не лучше а даже медленнее
А если не на каждом шагу проверка нужна то можно и без if'а, и без локальных except (только большой "всё-ловящий" try/except)
Я тоже за подход, что легче просить прощения, чем разрешение. Спасибо за прекрасный материал.
суперская подача инфы, больше видео как надо и как не надо !)))
Спасибо мужик!
У тебя много что узнаю. Только уважение к тебе.
Спасибо!
Спасибо ,как всегда огонь инфа!
Хороший ролик, спасибо :)
Спасибо за выпуск. Хорошо прояснил официальные подходы !) Круто!
Можно ли еще видео как до этого было, часовое по django, очень зашел формат, только по django REST)
Круто снял!
Очень давно так делаю, теперь просто знаю как это называется )))
Спасибо за контент!
Алексей, круто! Спасибо большое) Очень бы хотелось побольше подобных видео о лучших практиках
Вообще, слышал такое мнение: если знаешь что может пойти не так - используй if-else, так как исключение в питоне довольно медленные. Сами же исключения используются для исключительных ситуаций, когда что то идет не так из за внешних факторов. То есть в примере с диктом я бы использовал if else, в случае сетевого взаимодействия или дискового - уже исключения.
Да чем всех dict.get( ) не устраивает?
Как всегда отличное и полезное объяснение по делу! Спасибо!
Спасибо! Как всегда отличная подача и полезная информация!
Очень полезное видео! Спасибо!
Полезная инфа
Добрый коммент=)
спасибо:)
офигенное видео, спасибо!
Спасибо за контент! Нужно скинуть в чаи группы, им должно понравиться)
Блин, почти не использовал try/except в своем коде, везде пихал if/else. А после этого видео, буду писать правильно. Спасибо!!!
Спасибо за годноту, а когда будут выпуски про aiohttp?
Скоро будут!
Спасибо! Как раз вот пишу код и думаю об этом. Очень кстати! Было бы супер как-нибудь поглядеть на код модульных тестов, которые в том числе проверяют такие ветки с прерываниями, чтобы велосипед не изобретать.
Обожаю свои программы заворачивать снизу доверху в except Exception! Правда я обычно пишу сервероподобный софт, а такие вещи делаю, чтобы весь процесс не упал из-за пропущёной запятой в тридевятой вьюхе.
God bless you!
Спасибо!
В первом примере LBYL подхода, должен быть еще else с выводом текста об не найденном ключе))
Классный формат, рассказывать про такие маленькие фичи. И понимание зена возрастает, и код лучше будет
А что насчет скорости выполнений? Читал, что try/except выполняются медленнее, чем условия, поэтому в своём коде обычно их не использую.
@@avazart614 и не про чистоту кода, по всей видимости
А я вместо кучи ифов пользуюсь свичкейзом через метод словаря .get(key, default=None). Получается очень красиво и читаемо!
Хороший ролик, лайк!
Дааа, .get очень удобный метод, тоже часто использую!
Спасибо!
Круто!
Злой комментарий)))
Спасибо за видео!
Спасибо, лайк!
С меня предоставляется коммент за годный контент! Жаль, что задонатить не могу(
Пасиб)
Есть мнение, что содержимое try выполняется 2 раза. 1й раз на пробу брода, 2й раз на переход брода. Поэтому если много проходов по траю - будет растрата ресурсов
В примере не совсем понятно, какое требование стоит в ТЗ. Т.к. в зависимости от этого может быть и If лучше, если ключа у нас действительно может не быть в словаре.
Почему-то вы изначально за аксиому взяли, что нормальное поведение - это когда ключ есть. А если это не так? То нормальным будет уже if...
Да и к тому же пример с if не полон, если добавить туда else с выводом той же ошибки, то разница уже не так очевидна.
И почему во втором примере нельзя написать так?
try:
with open(tmp_file) as f:
print(f.read())
except IOError as e:
print("Error")
наверно что бы можно было понять где падает open а где read. Но это как то нелепо описывать условную логику через эксепшены.
Ээээ...круто)
Очень, очень не нравятся блоки try except в коде.
Единственный момент, когда могу пойти на компромисс - это интеграции - различные запросы. Но при возможности, закидал бы камнями разрабов в момент разработки либ, методы которых бросают исключения (привет request timeout error).
Мало того, что сами блоки занимают много места и делают код менее читабельным, так некоторые просто напишут "except: pass" и спят спокойно.
Да и в целом... все ошибки не переловишь и этот домик из "except ...: ..." может расти и расти.
И это одна из причин, почему перехожу потихоньку на Golang и пишу не dictionary[key], а dictionary.get(key) и обрабатываю None.
С файлом пример понравился, но будем надеиться, что, во время работы с ним одного потока, другой не делает критических изменений с флогом "w+".
Все в видео очень лаконично и ясно, будто хороший код на питоне. :)
Вопрос, почему часто читаю в книгах по computer science, что использование исключений является не очень хорошей практикой программирования? И даже при создании своего языка Goland авторы, например, решили отказаться от поддержки исключений. Чем это вызвано?
Потому что исключения начинают использоваться не по назначению, они разворачивают стек вызовов и добавляют оверхед по производительности и потребляемой памяти только ради того, что бы программисты смогли снова вернуться во времена оператора goto. Исключения добавляют неясности в кодоввю базу и надо усердно курить мануалы что бы понять может ли какая то функция прокинуть ошибкуи и в каких ситуациях
Отлично рассказываете! У вас есть видео об ООП в python? Если нет, то было бы круто от вас услышать базовые вещи об этом! Спасибо за ваш труд!
В защиту LBYL скажу, что сейчас в python есть довольно много инструментов, с помощью которых можно делать подобные проверки красиво и прозрачно. К примеру, библиотека trafaret. Всегда её использую при обработке тела запроса клиента на сервер.
я, в последнее время перешел 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, что бы это не значило :).
@Вячеслав Украинцев так и есть. Поэтому они не про вадидацию. Но тут сторонняя библиотека, ну и асерты, прямо по назначению, я что-то и не использовал никогда.
не знаю что написать но напишу)
Хотел спросить. Будут ли видео по Flask? На мой взгляд это очень показательный фреймворк, т.к. есть большая свобода действия.
А че) очень полезно)
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 потребляет больше ресурсов чем if, python для блока try копируются все переменные и уже с копиями выполняются операции из блока try чтобы не запороть основной цикл программы и не испортить переменные если код в try свалиться в исключение и продеться откатывать
Было бы интересно от вас послушать как SOLID применяются в Python. Думаю тема достаточно непростая и очень важная!
github.com/heykarimoff/solid.python
добрый комментарий
добрый комментарий
добрый комментарий
Хахаах, спасибооо!
Отличное видео! Алексей, когда же будет запуск обучения?
Скоро-скоро!
Я не спрошу "что такое принцип EAFP", я спрошу "кто такие котаны или катаны"
Те кто отключают интернет во время деплоя))
Анонсируйте подалуйста примерную дату курсов
Огромное спасибо за видео, хоть пока мне и без толку данная информация (не тот уровень скила), но прям от видео веет дружеским наставничеством.
Было бы кстати неплохо посмотреть ваш подход к началу проекта, с чего стоит начинать писать.
P.S. А mailto:mailto: так и не исправили :-)
Злой писать не охота, а вот добрый, пожалуй, оставлю. У меня такая проблема. Год назад начал изучать Питона вообще с нуля. С такого уровня, что вообще первый раз открыл cmd. Сейчас пишу программы для своего бизнеса, но у меня нет развития, потому что имеющиеся знания покрывают потребности моего дела. Я понимаю, что с таким уровнем ни в какую компанию не попадёшь, а хотелось бы связать себя с профессией программиста. Прямо беда. Хочу развиваться, но вместо этого бег на месте.
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.
Денис Борисов от software enginering
почему?
Хороший Рол вкусный! Хорошо зашёл) Кто такие Катаны? «здорова Катаны»
Думаю, что имеется в виду кОтаны. Ну т.е. мальчики выросшие из котяток... 😃
Когда будет урок про git? В первых видео обещали, но так и не разобрали данную тему :(
Сейчас на работе пришлось самому разбираться. Очень жалею что не юзал это раньше.
Я писал в 2013м статью по базовому гиту - goloburdin.blogspot.com/2013/11/git-bitbucket-20.html
Видео тоже планирую, просто хочется сделать что-то глубже, чем просто commit/pull/push/merge/checkout
Как вас вообще на работу взяли)
А я думал, что try/except как раз для того, чтобы минимизировать ветвления и обработчики исключений, оставив один обработчик по умолчанию на самом верхнем уровне.
4:56 у вас при исключении файл не закроется.
И кстати конструкция with закрывает файл после действий, но здесь это не поможет.
А почему нет блока else, он нужен чтобы сообщить что ключа нет! )
4:44 а разве не лучше считывать тоже в блоке try? Вдруг во время чтения что-то произойдёт.
А, точно после открытия файла для чтения файл полностью принадлежит процессу и ошибки быть не может... поэтому покрасивше будет выделить чтение в блок else
Вроде сишники (особенно эмбеддщики) говорят, что исключения какие-то дорогие и слишком медленные из-за того, что там какие-то манипуляции со стэком происходят. Это правда?
Письмо от хейтера (шутка, уважаю твой канал).
Внезапно, в Rust лучше реализованы принципы Python, чем в самом Python: и принцип "явное лучше неявного", и принцип "EAFP", а в качестве бонуса ещё и статическая типизация и всё это делается без исключений.
value = some_hashmap.get("key")? // Передача ошибки выше по стеку
value = some_hashmap.get("key").unwrap(); // Ленивый вылет из программы
value = some_hashmap.get("key").expect("Нет тут такого ключа"); // Чуть более сложный вылет
Всё в одну строку.
Ну, и говорить о преимуществе одной константной операции вместо двух... На python?.. Гм... Ну, такое
До ржавчины пока руки не дошли, но на досуге хочу познакомиться. Хотя блин кого я обманываю, какой нахрен досуг))
Но исключения - это очень дорогое удовольствие, их стоит-таки избегать, если это возможно.
в чем дороговизна, поясните плз.
нет никакой дороговизны, по крайней мере в случае CPython.
stackoverflow.com/questions/2522005/cost-of-exception-handlers-in-python
docs.python.org/3/faq/design.html#how-fast-are-exceptions
@@ИванОмельченко-б7в абсолютно согласен с вами. На первое место в питоне надо ставить читабельность и простоту кода.
Последний фрагмент кода нужно было написать так, чтобы *try-except* был внутри функции?
try:
something = some_dict["key"]
except KeyError:
# do some stuff
pass
else:
some_func(something)
Напр, так
В 1с использование такой конструкции считается плохим тоном.
Значит программист плохо учел возможные варианты, раз у него что-то может вызвать исключение.
1C сам по себе считается плохим тоном.
P.S. Ладно, шутка
@@СергейПресняков-о4р давай напишем систему лучше) Аналогов я не нашел, ниша свободна.
Не шутка)
Знаю, вопрос не по теме, и скорее всего, вы даже не ответите на него. Я знаю что вы используете MacOS также стандартный терминал, мне очень понравился шрифт с терминала, поискал узнал что стандартный шрифт в Терминале MacOS это Lucida Grande, погуглил, посмотрел, похоже но не то, последний способ был написать вам, больно уж нравиться мне шрифт в вашем Терминале. Заранее Спасибо.
У меня шрифт Monaco в терминале
@@t0digital Спасибо вам большое
Добрый и злой комментарий. Написал как ты попросил))
Зачем вы сделали бейсбольный мячик своим крестражем?
я так и не понял объясните еще раз- нужно всегда проверять есть ли ключ в структуре данных и потом его применять?
Всегда не надо, надо, когда есть вероятность, что ключа нет в словаре. Когда что-то может пойти не так в программе, на это надо заложиться
@@t0digital вот на фронтэнде так всегда приходится делать потому сервера часто падают и поэтому в большинстве случаев так приходится делать
Аригато козаимасу:)
Как можно сравнивать разный функционал? Если вместо каждого if использовать try except то не только сложно будет читать, но и выполняться такая программа будет намного дольше.
Так и не предлагается везде заменить if на try/except
А точно стоит ронять весь код ради ключа/файла?
В логи записать ERROR недостаточно будет?
Ронять весь код не надо, если это не фатальная проблема, с которой невозможно продолжать. Обработка исключений и eafp и позволяет не убивать программу.
Что там по курсу??
Насчет больших блоков кода отчасти не согласен, формально нас никто не ограничивает от большого числа except's, на этом тоже вполне можно строить логику скрипта, если вводятся собственные унаследованные классы исключений. Например, если у нас есть сервис который должен крутится в улсовном бесконечном лупе, то отказ от оборачивания кода в целе лупа может привести просто к его паданию и остановке всего, с другой же стороны, если мы ловим исключения в основной логике и кажется, что предусмотрели все, то в блоке лупа есть возможность залогировать исключение с трейсбэком и признаться, что мы что-то да не предусмотрели. Мне кажется, что это более правильный подход, впрочем видео то не про это, просто немного привязался к финальным фразам.