Почему подклассы tuple и str не поддерживают слабые ссылки в Python? - PullRequest
1 голос
/ 13 февраля 2020

Начиная с версии 3.8, Python документация о слабых ссылках состояния:

Несколько встроенных типов, таких как list и dict, напрямую не поддерживают слабые ссылки но может добавить поддержку с помощью подклассов.

CPython подробности реализации: Другие встроенные типы, такие как tuple и int, не поддерживают слабые ссылки, даже когда подклассы.

Ранее задавался вопрос , какие типы поддерживают слабые ссылки и , почему встроенные типы не поддерживают слабые ссылки , но почему встроенные типы, такие как tuple и int не поддерживает слабые ссылки в CPython?

1 Ответ

3 голосов
/ 13 февраля 2020

Тот факт, что встроенные типы не поддерживают слабые ссылки (а также не поддерживают динамические атрибуты c), является деталью реализации. Как правило, слабые ссылки (и динамические атрибуты c) не нужны. Отсутствие их поддержки позволяет уменьшить объем структур данных для встроенных типов и повысить эффективность операций с ними. Так как эти типы (особенно кортежи и dict) используются во всей внутренней реализации Python, стоит использовать более производительную реализацию.

Это охватывает встроенные типы, но как насчет подклассов?

Способ реализации слабых ссылок в настоящее время заключается в том, что каждый класс определяет фиксированное смещение памяти, где каждый экземпляр хранит ссылку на контейнер, содержащий его слабые ссылки. Это фиксированное смещение может быть указано для объектов конечного размера, таких как float, потому что данные экземпляра имеют фиксированный размер, и поэтому указатель слабой ссылки может быть установлен с фиксированным смещением после этих данных. Изменяемые объекты, такие как dict и list, хранятся в памяти двумя частями. Первая часть содержит неизменяемые данные, относящиеся к экземпляру, включая указатель на вторую часть, которая содержит изменяемые данные (например, массив, содержащий содержимое списка). Поскольку первая часть данных экземпляра имеет фиксированный размер, также возможно указать фиксированное смещение указателя слабой ссылки для этих изменяемых типов. Проблема с str и tuple заключается в том, что они оба неизменны и имеют разные размеры. Каждый экземпляр хранит все свое содержимое в своем отдельном блоке памяти. Таким образом, класс не может указать фиксированное смещение для указателя слабой ссылки, действительное для всех экземпляров. Сначала я был озадачен, почему int не может быть слабой ссылкой, как float. Затем я обнаружил, что экземпляры int в Python занимают переменный объем памяти в зависимости от значения целого числа .

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

Примечание: этот ответ основанный на двух сообщениях ( здесь и здесь ), сделанных Раймондом Хеттингером для рассылки python в список 30 марта 2005 года с темой "Слабые ссылки на классы, полученные из str. «). Я предоставляю дополнительную информацию о дате и теме, потому что ссылки списка рассылки python, похоже, со временем меняются, но их легко можно найти по дате и теме.

...