__new__ and __init__ - why does this work?

Ian Pilcher arequipeno at gmail.com
Wed Aug 9 15:59:20 EDT 2017


On 08/09/2017 07:54 AM, Steve D'Aprano wrote:
> On Wed, 9 Aug 2017 10:08 am, Ian Pilcher wrote:
> 
>> I have created a class to provide a "hash consing"[1] set.
> 
> Your footnote for [1] appears to be missing. What's a hash consing set? It
> appears to be nothing more than frozen sets which you put in a cache so as to
> confuse identity and value *wink*

Uugh.  Here's the link:

   https://en.wikipedia.org/wiki/Hash_consing

> I doubt very much you're actually saving any time, since you create a temporary
> frozen set before returning the one in the cache. You might save some memory
> though.

Indeed.  This is all about using memory efficiently.

> Your __init__ method does nothing. Get rid of it and save two lines of code :-)

Well, it prevents frozenset.__init__ from being called.

> Also, there is at least theoretically the vague possibility that
> frozenset.__init__ does something (phones home to Guido?) so you shouldn't
> block it if you don't need to.

I do want to prevent frozenset.__init__ from being called *again* when
an existing instance is returned, so I've decided to take this
approach:

     def __new__(cls, *args, **kwargs):
         self = super(UniqueSet, cls).__new__(cls, *args, **kwargs)
         self._initialized = False
         return UniqueSet._registry.setdefault(self, self)

     def __init__(self, *args, **kwargs):
         if not self._initialized:
             super(UniqueSet, self).__init__(self, *args, **kwargs)
             self._initialized = True


-- 
========================================================================
Ian Pilcher                                         arequipeno at gmail.com
-------- "I grew up before Mark Zuckerberg invented friendship" --------
========================================================================




More information about the Python-list mailing list