Python Empty Immutables Singletons ли са?

Python Empty Immutables Singletons ли са?

Ако прегледате реализацията на 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 откриха аналитично, означава, че коментарът, Празният frozenset е сингълтън в най-добрия случай е подвеждащ и според мен е просто грешен.   -  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“ в този контекст се използва различно от общоприетото й значение. В тази публикация 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 тип, те по дефиниция не са сингълтони. Не съм сигурен, че са гарантирани от спецификацията, че са глобално уникални екземпляри, но изглежда, че действат като borgs, поне в C Python. - person Silas Ray; 13.08.2014
comment
@SilasRay - Въпреки че това е правилното определение, това не е определението, което OP имаше предвид, когато каза сингълтън. Използвам дефиницията на OP, която е по-скоро като стойност, която може да се съхранява само от един обект. - person Robᵩ; 13.08.2014