Обновить
8K+
170
Никита Соболев@sobolevn

Fulltime OpenSource разработчик

52,2
Рейтинг
499
Подписчики
Отправить сообщение

Нет, как раз сам объект и изменяется:

>>> b = bytearray(b'123')
>>> b
bytearray(b'123')
>>> b.take_bytes()
b'123'
>>> b
bytearray(b'')

Потому что они не делают freeze :) Они забирают данные из готовых мутабельных структур и создают новые иммутабельные.

К сожалению, f[1] - валидный синтаксис сейчас. Потому я и предлагал $. Но, люди отказались по причине (я не шучу): "мы не хотим $ как в php". Вот так программисты принимают технические решения 🌚️️

Мешает :(

Сейчас, мы не знаем, что такое Final в момент компиляции. Final может быть ваш собственный класс.

  1. Аннотации могут быть ленивыми

  2. Они могут быть строками

  3. Они могут быть вообще не определены в рантайме в форме: if TYPE_CHECKING: from typing import Final

Как такое нормально превратить во что-то адекватное на шаге symtable? Я не знаю. И никто не знает :(

Да и проблему оно описанную в посте не решит; `d: Final = {1: 2}` все еще поддерживает (по текущей typing spec) все действия над dict, в том числе `d[3] = 4`.

А еще их можно будет дешево шарить в субинтерпретаторах, да :)

Final не обозначет "иммутабельность", он обозначает "запрет" на re-assignment. Что разные вещи :) Суть frozendict в том, что его нельзя изменить. Такое очень полезно для большого количества задач. Например: данные request, которые пришли к вам от пользователя. Или какой-то контекст, настройки приложения, справочники, тд. Более того, с Free-Threading by default, такое станет еще нужнее. Я предлагаю начать готовиться заранее, а не срочно в 30м году все переделывать.

dambung_tsss 🌚️️

Вы совершенно правы :) Сейчас есть похожая штука: сравните

» ./python.exe -m dis <<< 'dict(a=1, b=2)'      
  0           RESUME                   0

  1           LOAD_NAME                0 (dict)
              PUSH_NULL
              LOAD_SMALL_INT           1
              LOAD_SMALL_INT           2
              LOAD_CONST               1 (('a', 'b'))
              CALL_KW                  2
              POP_TOP
              LOAD_COMMON_CONSTANT     7 (None)
              RETURN_VALUE

И:

» ./python.exe -m dis <<< '{"a":1, "b": 2}'  
  0           RESUME                   0

  1           LOAD_CONST               0 ('a')
              LOAD_SMALL_INT           1
              LOAD_CONST               1 ('b')
              LOAD_SMALL_INT           2
              BUILD_MAP                2
              POP_TOP
              LOAD_COMMON_CONSTANT     7 (None)
              RETURN_VALUE

Вроде разница не очень большая, но: BUILD_MAP работает так:

inst(BUILD_MAP, (values[oparg*2] -- map)) {
    PyObject *map_o = _Py_BuildMap_StackRefSteal(values, oparg);
    DEAD(values);
    ERROR_IF(map_o == NULL);
    map = PyStackRef_FromPyObjectStealMortal(map_o);
}

Где _Py_BuildMap_StackRefSteal делает тоже самое, что и простой вызов _PyDict_FromItems. Ну а CALL_KW - один из самых медленных опкодов вообще.

Спасибо за вашу обратную связь! Вашу позицию не разделяю, но уважаю :)

to_bytes не уничтожает существующий int, а просто конвертит его. а тут нужен явный глагол, который бы показывал, что само левое значение обнулится:

>>> b = bytearray(b'123')
>>> b
bytearray(b'123')
>>> b.take_bytes()
b'123'
>>> b
bytearray(b'')

В питоне такое назвали take_* :)

Но ведь frozenset(iterable) не позволяет нормально оптимизировать код. В обсуждении по ссылке как раз есть примеры, почему так сделать нормально не получится. Сравните опкоды `frozenset({1, 2})` и `frozenset((1, 2))`. В том же обсуждении есть примеры, почему .take_frozenset и .take_frozendict не могут быть единственными дешевыми конструкторами. Например: при многострочных выражениях - непонятно, какой тип будет у объекта до самого конца. И другие важные штуки.

Как знание английского языка помогает вам понять `{1: 2}`? В чем принципиальное отличие от `f{1: 2}`?

Я не знаю, почему люди так хотят :)

Как я писал выше, я был за $. Но демократия решила иначе.

я не думаю, что тут есть реальная проблема. вы же просто помните, что {} - словарь; вот так же и f{} - иммутабельный словарь.

Я почти ничего не понял :)

set.take_frozenset и dict.take_frozendict - разные методы для разных типов. их названия точно отражают то, что происходит внутри. Зачем сокращать названия builtin классов - не очень понятно.

почему не стали использовать что нибудь типа myset as frosen?

Потому что в питоне нет концепции кастов. as используется для создания имен, а не типов. Добавлять такое - точно не надо :)

Как будет проверяться что frosen?

Не очень понял вопрос. Как и сейчас? isinstance(obj, frozenset)

Форматтер строки к сетам/диктам

Нет, форматтер строки тут не при чем. Мы добавляем новый токен f{, который называется FLBRACE, по аналогии с { (LBRACE).

а с автодополнением f{1,2,3} в vscode превратится в строку

Автодопонение будет работать корректно. Сейчас же `{1, 2, 3}` не превращается в строку. И `f{1, 2, 3}` не будет. Не думаю, что тут могут возникнуть проблемы.

Да, таков наш план. Вот тут было первое голосование https://discuss.python.org/t/frozenset-and-frozendict-comprehensions/101584/48 Люди хотят, чтобы было похоже на f строку :) Я сам был за $

Есть! Мы ее обязательно выпустим!

Отличный туториал! Вот бы еще и линтер по правилам из статьи 🌚

Статья вышла без указания оригинала!!! Оригинал был озвучен на митапе PythoNN в Нижнем Новгороде. Куда я вас всех приглашаю следующий раз :)

Информация

В рейтинге
136-й
Зарегистрирован
Активность