Pull to refresh

Comments 19

Поэтому хороший стиль — не писать return внутри finally. Это почти всегда делает код менее предсказуемым и может «поглотить» результат из try или даже исключение из except.

А ещё это приведёт к SyntaxWarning исключению в Python 3.14: PEP765 и не просто "хороший стиль", а не рекомендуется официально.

Спасибо за комментарий!

Однако добавлю, что это пока не исключение, а предупреждение (SyntaxWarning) — просто на уровне языка теперь обращают внимание на такие случаи.

Вообще, 3.14 принесла много интересных изменений, надо будет отдельно про них написать!

Пришел такой челик считать ядерные реакции или датасайнс мл лёрнер, знает матан вдоль и поперек, а ему - сорян бро, ты не знаешь чем eval от exec отличается, пиу пиу пиу 😂

Ну так роли ведь разные бывают. Если человек идёт на позицию, где важен матан, то его сильная сторона как раз там — и логично, что пробелы по питону не критичны. А если наоборот — вакансия завязана на кодинге и питон основной инструмент, то странно игнорировать, что кандидат путается в базовых вещах. Не спросишь же у питон-разработчика интегралы, просто потому что “вдруг знает матан”.

Ну, на самом деле сеньор программист выше прав в чём-то.

Я использую Python как основной язык уже 16 лет. Но про округление узнал из вашей статьи ("ах вот, блин, в чём дело, коза его дери!")

Про return внутри try - я смутно помню что читал что-то про поведение, изменённое в какой-то из версий, но через меня столько этих версий прошло, что мне пришлось загуглить это. На собеседовании я бы мямлил типа "да, что-то там было, но точно не помню, да, ага...". Хотя, мужду прочим, else есть и у try-except блока и на собеседовании могли бы спросить что-то типа "а что выполнится если будет конструкция try-except-else-finally и в каждой будет return?"

Разницу между str() и repr() я бы сходу не ответил, или ответил бы так, что это вполне можно было бы как замечание зачесть..

exec и eval я не использую давно, однако лет 10 назад писал парсер через AST чтобы для exec фильтровать допустимый текст, но, опять же, не вспомню ничего оттуда сразу без гугла.

Теперь можно безопасно полагаться на порядок словаря

Нет, нельзя не стоит. Для сохранения порядка ключей в словаре используйте OrderedDict, потому что природа словарей, как и любого другого Map - не полагаться на порядок вставки элементов. Текущее поведение - побочный эффект оптимизации использования памяти словарями, в будущих версиях Python все может измениться. Если не ошибаюсь, то даже в доках это где-то указывалась.

многие до сих пор уверены, что «в словарях порядок случайный»

Хе-хе.

  • До Python 3.6 — порядок ключей считался произвольным: итерация по dict не обязана была соответствовать порядку вставки. Это прямо зафиксировано в документации (и нигде не было обещаний про порядок).

  • Python 3.6 (CPython) — появился новый, компактный алгоритм хранения словарей («compact dict»), благодаря которому порядок вставки стал сохраняться как побочный эффект реализации

  • Python 3.7 (все реализации Python) — сохранение порядка вставки стало требованием языка. То есть с 3.7 вы можете полагаться на порядок вставки для обычных dict. Ссылка.

Долго не отвечал - был в шоке. Получается, что я был не прав, однако не могу одобрить такого решения.
От себя я бы всё-таки рекомендовал использовать OrderedDict там, где важен порядок ключей, этим вы как бы говорите коллегам - "тут нам очень важен порядок ключей, и это не просто так". Речь, конечно же, про код, который нужно сопровождать, в одноразовых скриптах это не важно.

Не одобряю изучение языка как подготовку к собеседованию. И уж тем более не одобряю такие вопросы на собеседованиях. Цель собеседования — проверить мышление кандидата и по возможности то как он работает в команде. Но сама подборка неплохая, многие вещи вспомнить вполне не лишне.

@homm Полностью согласен. Именно так я и поступаю на своих собеседованиях. Однако важно уточнить, что статья не о самих вопросах, а об особенностях языка, которые необходимо понимать перед собеседованием. Большинство вопросов и задач как раз строятся вокруг этих особенностей, поэтому их знание и понимание действительно имеет значение.

Если на это будет спрос, то, конечно, напишу. В Python есть множество интересных особенностей, которые часто упускают из виду.

В довесок к цепочным присваиваниям и тождественности любят спрашивать почему a и b ссылаются на один объект, а c и d на разные, хотя объявлены они одинаково.

>>> a = 1
>>> b = 1
>>> c = 1111
>>> d = 1111

a is b # True
c is d # False

>>> id(a)
140712275936168
>>> id(b)
140712275936168

>>> id(c)
1894793473328
>>> id(d)
1894793471632
  • Ответ: может что-то про интернирование? И вообще нефиг использовать is для проверки скалярных значений.

  • Ответ со звёздочкой: CPython заранее создаёт объекты для чисел в определённом диапазоне. Эдакий кэш.

    • Ответ с двумя звёздочками, если называется диапазон (до 3.13 включительно это от -5 до 256).

    • Ответ со звездой героя: диапазон менялся по ходу разработки, от -5:128 до текущего -5:256, а скоро он будет от -5 до 1024.

Интересно, как выбирался диапазон? Какую то статистику использования собирали?

И вариант для звезды героя-героя: будет ли интернирование для строки "интернирование"?

Интересно, как выбирался диапазон? Какую то статистику использования собирали?

По официальной документации: "The values for NSMALLPOSINTS and NSMALLNEGINTS are chosen based on the most commonly used integers in typical Python programs".

Но я бы сказал, что никакого анализа не проводилось, этим диапазонам сто лет в обед, вряд ли кто-то парсил тонну исходных кодов в то время, чтобы собрать статистику. Скорее всего, это интуитивно выбранный диапазон для целочисленных и битовых масок, ну и всяких флагов вдобавок.

И вариант для звезды героя-героя: будет ли интернирование для строки "интернирование"?

Кроличья нора на самом деле довольно глубока. Пример из моего комментария выше сработает в интерактивном интерпретаторе. Однако, если создать файл с таким же содержанием a=1 b=1 c=1111 d=1111 print(a is b) print(c is d), то ответ будет... True True. И это интересный вопрос для продолжения обсуждения.

Причина тому кроется в том, что в интерактивном режиме каждая строка обрабатывается отдельно в момент ввода, тогда как файл будет обработан целиком. И если сделать dis.dis() и func_code.co_consts() на функцию, которая содержит кусок кода выше, то будет видно, что LOAD_CONST, STORE_FASTинстанцируют только один объект.

---

Что касается интернирования строк, то я лично такой вопрос на собеседованиях не встречал и сам не задавал (впрочем, вопрос про целочисленные приколы я тоже не задавал). Но оно есть и в нём интересно покопаться.

>>> a = 'hello'
>>> b = 'hello'
>>> a is b
 True
>>> c = 'hello world'
>>> d = 'hello world'
>>> c is d
 False

Интернируются строки длиной до 4096 (лимит, опять же менялся), не содержащие пробелы, символы за пределами буквенного диапазона ascii и т.п. Поэтому "интернирование" не попадает и интернировано не будет, а вот английское слово сработает - дискриминация :). При этом подчёркивание интернируется, а дефис нет. Помнить всё это бессмысленно, практической пользы это несёт мало, разве что показывает, что кандидат копался под капотом Python и умеет пользоваться dis.dis().

А кто то в какой то либе возьмёт и интернирует. А кто то будет полагаться на то что не интернировано. (интернировать можно что угодно)

Кину свои пять копеек про изменяемые аргументы по умолчанию

Смотрим:

def add_item(item, my_list=[]):  # треш
    my_list.append(item)
    return my_list

print(add_item(1))  # [1]
print(add_item(2))  # [1, 2] втф

А все потому что [] создается ОДИН РАЗ при загрузке функции и живет там как синглтон. Каждый вызов без аргумента тащит тот же самый список

Фикс простой, юзаем None:

def add_item(item, my_list=None):
    if my_list is None:
        my_list = []
    my_list.append(item)
    return my_list

В первой части это уже рассмотрели:)

Sign up to leave a comment.

Information

Website
practicum.yandex.ru
Registered
Founded
Employees
101–200 employees
Location
Россия
Representative
Ира Ко