Являются ли Python пустыми неизменяемыми синглтонами?

Являются ли Python пустыми неизменяемыми синглтонами?

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

Вот, в частности, источник для 2.6, который ссылается на заморозки. Объявляется как комментарий:

/* The empty frozenset is a singleton */

Я нахожу тот же комментарий и в CPython 2.5. Я думаю, имеет смысл ссылаться на источник в дополнение к документации, потому что CPython является эталонной реализацией Python.

Я использую Python 2.6.5 и получаю в интерпретаторе следующий результат:

>>> g = frozenset()
>>> f = frozenset('a') - frozenset('a')
>>> f
frozenset([])
>>> f is g
False
>>> id(f)
279262312
>>> id(g)
114734544

Значит ли это, что комментарий неправильный? Это ошибка в 2.6.5? Это гарантировано в более поздних версиях Python? Если это так, я не могу найти ссылку на него в документации.

Я спрашиваю это, потому что мне нужен чек, идентичный членству в (None, ''), но причина в другом.

Не поэтому ли считается лучшей практикой использовать is для проверки None и использовать == или семантическую ложность пустых типов Python для потока управления, относящегося к другим типам?

Подводить итоги:

Гарантируется ли, что пустые неизменяемые объекты Python являются синглтонами?


person Aaron Hall    schedule 12.08.2014    source источник
comment
В исходном коде, на который вы ссылаетесь, frozenset() является одноэлементным, а frozenset(iterable) всегда является новым объектом, даже когда iterable оказывается пустым. Плюс тот факт, что это комментарий в исходном коде одной реализации, а не примечание в документации, означает: Нет гарантии и нет смысла беспокоиться об этом.   -  person    schedule 13.08.2014
comment
@delnan В дополнение к этому, копаясь в коде C, frozenset фактически использует set богатые методы сравнения, а также использует set_difference_multi для его метода различия, которые все создают новые экземпляры множества для результата независимо от того, какие входные данные они получают. Поскольку OP запускает __sub__ под прикрытием, пустая одноэлементная оптимизация в frozenset_new совершенно не имеет значения.   -  person Silas Ray    schedule 13.08.2014
comment
Поведение, которое OP обнаружило эмпирически, а @SilasRay и delnan обнаружили аналитически, означает, что комментарий Пустой замороженный набор является синглтоном в лучшем случае вводит в заблуждение и, на мой взгляд, просто неверен.   -  person Robᵩ    schedule 13.08.2014
comment
@Robᵩ Это просто демонстрирует, что комментарии / = документация. Комментарий является точным локально в контексте функции frozenset_new, но не применим глобально.   -  person Silas Ray    schedule 13.08.2014


Ответы (1)


описание стандартных типов не обещает, что эквивалентные объекты идентичны, за исключением True, False, None, NotImplemented и Ellipsis. Некоторые из обещаний, которые он не дает, относятся к () is (), 1 is 1 и 'hello' is 'hello'. (На самом деле документация специально отклоняет требование 1 is 1 в последнем абзаце 3.1.)

Нет, пустые неизменяемые контейнеры Python не обязательно являются одиночками*. Единственными гарантированными синглтонами являются True, False, None, NotImplemented и Ellipsis.



* Примечание: слово "singleton" в данном контексте используется не в его общепринятом значении. В этом посте синглтон означает значение, которое может храниться только одним объектом; отсюда следует, что каждый объект, содержащий это значение, идентичен.

person Robᵩ    schedule 12.08.2014
comment
Плюс один, заметив решительное заявление о том, что 1 is 1 не гарантируется (вероятно, следует ссылаться на него), а также гарантированные NotImplemented и Ellipsis, я тоже их заметил. - person Aaron Hall; 13.08.2014
comment
Разве True и False не следует также считать синглтонами? - person Jimmy C; 13.08.2014
comment
Два объекта, представляющие значения False и True, являются единственными логическими объектами. Ага. Спасибо, @JimmyC - person Robᵩ; 13.08.2014
comment
@JimmyC Технически синглтон — это класс, который может иметь только один экземпляр, и, поскольку True и False оба относятся к типу bool, они по определению не являются синглтонами. Я не уверен, что спецификация гарантирует, что они будут глобально уникальными экземплярами, но похоже, что они действуют как борги, по крайней мере, в C Python. - person Silas Ray; 13.08.2014
comment
@SilasRay - хотя это правильное определение, это не то определение, которое имел в виду ОП, когда говорил «синглтон». Я использую определение OP, которое больше похоже на значение, которое может храниться только одним объектом. - person Robᵩ; 13.08.2014