Interning own classes like strings for speed and size?

Christian Heimes lists at cheimes.de
Tue Dec 28 09:46:25 EST 2010


Am 28.12.2010 15:11, schrieb Steven D'Aprano:
> # Untested
> class InternedTuple(tuple):
>     _cache = {}
>     def __new__(cls, *args):
>         t = super().__new__(cls, *args) 
>         return cls._cache.setdefault(args, t)
>     def __eq__(self, other):
>         return self is other
>     def __ne__(self, other):
>         return self is not other

The code doesn't work, you have to change super().__new__(cls, *args) to
super().__new__(cls, args). Don't ask me why. I'm surprised, too.

>>> InternedTuple(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __new__
TypeError: 'int' object is not iterable


Also this code is going to use much more memory than an ordinary tuple
since every instance of InternedTuple has a __dict__ attribute. This
code works but I had to move the cache outside the class because of
__slots__.

_ituple_cache = {}

class ituple(tuple):
    __slots__ = () # no __dict__

    def __new__(cls, *args):
        cached = _ituple_cache.get(args)
        if cached is not None:
            return cached
        self = _ituple_cache[args] = super(ituple, cls).__new__(cls, args)
        return self




More information about the Python-list mailing list