[Python, Программирование] Что вернёт эта функции в Python?
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Всем привет! Сегодня хотел бы обсудить очень простой, но, на мой взгляд, интересный вопрос по Python и его внутреннему устройству. Как вы думаете, что вернёт эта функция:
def foo()
try:
return 1
finally:
return 2
Если вам интересно, что получится в результате и как это работает, добро пожаловать под кат.Прежде чем давать ответ, давайте разберёмся, что происходит. Для начала рассмотрим самую простую функцию:
def foo():
return 1
Распечатаем её байт код:
import dis
dis.dis(foo)
Мы увидим следующий вывод:
2 0 LOAD_CONST 1 (1)
3 RETURN_VALUE
Рассмотрим по шагам:
- LOAD_CONST загружает константу (в нашем случае 1) и кладет её на вершину стека.
- RETURN_VALUE возвращает в вызывающий код значение с вершины стека.
Подробнее о байт-коде Python и его командах рассказано тут.Что же скрывается за мифической фразой «возвращает в вызывающий код»? На самом деле, никакой магии не происходит. Если обратиться к исходному коду CPython, то можно увидеть следующие строчки:
switch (opcode) {
...
case RETURN_VALUE: {
retval = POP();
why = WHY_RETURN;
goto fast_block_end;
}
...
}
Как видите, всё очень просто и понятно: мы сохраняем в переменной retval значение с вершины стека и переходим к выходу из текущего блока.Теперь мы готовы посмотреть на байт-код функции из нашего исходного примера. Как же она устроена внутри?
2 0 SETUP_FINALLY 8 (to 11)
3 3 LOAD_CONST 1 (1)
6 RETURN_VALUE
7 POP_BLOCK
8 LOAD_CONST 0 (None)
5 >> 11 LOAD_CONST 2 (2)
14 RETURN_VALUE
15 END_FINALLY
Опуская излишние подробности, этот код ведёт себя так:
- Устанавливаем блок try и указываем, где находится finally.
- Загружаем константу и возвращаем значение.
- Выполняем некоторые вспомогательные действия.
- Наконец идёт блок finally (адреса 11, 14, 15), в которым мы снова загружаем константу и делаем ret.
При исполнении кода сначала отрабатывает часть в блоке try, а затем выполняется код из finally. Что же происходит, когда мы снова вызовем RETURN_VALUE? Правильно, мы просто перезапишем возвращаемое значение retval на новое. Ну а функция, разумеется, вернёт 2.Как видите, даже несмотря кажущуюся неочевидность, Python, на мой взгляд, ведёт себя максимально понятно и логично: блок finally выполняется после блока try и его возвращаемое значение «более актуально». Однако, разумеется, на практике писать такой код я крайне не рекомендую ;-)
===========
Источник:
habr.com
===========
Похожие новости:
- [Python, Машинное обучение, Natural Language Processing] Нейрозапятые, или как мы оставили своих редакторов без работы (ну почти)
- [Программирование, Обработка изображений, Big Data, Машинное обучение] Помогите прочитать, что здесь написано? (OCR)
- [Программирование, Алгоритмы] Найти подстроку в строке
- [Программирование, Управление разработкой, Управление продажами, Карьера в IT-индустрии, Читальный зал] Дай таблетку, программист. Как в прошлый раз
- [JavaScript, Программирование, Node.JS] Как управлять несколькими потоками в Node JS (перевод)
- [Программирование, Венчурные инвестиции, Развитие стартапа, Образование за рубежом, Бизнес-модели] Перевод Курса по стартапам и бизнесу от Стэнфордского Университета. Лекция №3. Подготовка к созданию стартапа (перевод)
- [JavaScript, Программирование, Тестирование веб-сервисов, Машинное обучение] В закладки: репозитории с книгами, шпаргалками, ресурсами по дизайну и не только (перевод)
- [Open source, Python, Финансы в IT, Лайфхаки для гиков] Python-скрипт для импорта банковских расходов в Splitwise
- [Программирование, Java] Создание самодостаточных исполняемых JAR (перевод)
- [JavaScript, Программирование, Алгоритмы, Обработка изображений, Машинное обучение] Как мы создали Web приложение для определения лиц и масок для Google Chrome (часть 2) (перевод)
Теги для поиска: #_python, #_programmirovanie (Программирование), #_python, #_try, #_finally, #_return, #_vnutrennee_ustrojstvo (внутреннее устройство), #_interesnoe (интересное), #_osobennosti (особенности), #_blog_kompanii_domklik (
Блог компании ДомКлик
), #_python, #_programmirovanie (
Программирование
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:15
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Всем привет! Сегодня хотел бы обсудить очень простой, но, на мой взгляд, интересный вопрос по Python и его внутреннему устройству. Как вы думаете, что вернёт эта функция: def foo()
try: return 1 finally: return 2 def foo():
return 1 import dis
dis.dis(foo) 2 0 LOAD_CONST 1 (1)
3 RETURN_VALUE
switch (opcode) {
... case RETURN_VALUE: { retval = POP(); why = WHY_RETURN; goto fast_block_end; } ... } 2 0 SETUP_FINALLY 8 (to 11)
3 3 LOAD_CONST 1 (1) 6 RETURN_VALUE 7 POP_BLOCK 8 LOAD_CONST 0 (None) 5 >> 11 LOAD_CONST 2 (2) 14 RETURN_VALUE 15 END_FINALLY
=========== Источник: habr.com =========== Похожие новости:
Блог компании ДомКлик ), #_python, #_programmirovanie ( Программирование ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:15
Часовой пояс: UTC + 5