[Python-ideas] Revisiting Immutable Mappings

Philip Martin philip.martin2007 at gmail.com
Tue Oct 16 23:57:46 EDT 2018


I think it could inherit from the Mapping abc?

class frozendict(Mapping):
    def __new__(cls, *args, **kwargs):
        d = dict(*args, **kwargs)
        proxy = MappingProxyType(d)
        instance = super().__new__(cls)
        instance.__proxy = proxy

        return instance

    def __hash__(self):
        return hash(tuple(self.items()))

    def __getattr__(self, name):
        return getattr(self.__proxy, name)

    def __getitem__(self, key):
        return self.__proxy[key]

    def __iter__(self):
        return self.__proxy.__iter__()

    def __len__(self):
        return len(self.__proxy)

    def __repr__(self):
        return "%s(%r)" % (type(self).__name__, dict(self))


On Tue, Oct 16, 2018 at 4:29 AM Steven D'Aprano <steve at pearwood.info> wrote:

> On Tue, Oct 16, 2018 at 01:02:03AM -0700, George Leslie-Waksman wrote:
> > Would a frozendict require that keys and values be hashable?
>
> Keys, yes. Values, no.
>
> If the values were hashable, the frozendict itself would also be
> hashable. If not, then it would be like trying to hash a tuple with
> unhashable items:
>
> py> hash((1, 2, {}, 3))
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> TypeError: unhashable type: 'dict'
>
>
> > It seems to me that we would need this restriction to make a reasonably
> > universal frozendict that is, itself, hashable.
>
> When people talk about frozendicts being hashable, they mean it in the
> same sense that tuples are hashable.
>
>
> For what it is worth, here's an incomplete, quick and dirty proof of
> concept frozendict, using automatic delegation:
>
> # Not good enough for production, not tested, buyer beware, etc.
> class frozendict:
>     def __new__(cls, *args, **kwargs):
>         d = dict(*args, **kwargs)
>         proxy = types.MappingProxyType(d)
>         instance = super().__new__(cls)
>         instance.__proxy = proxy
>         return instance
>     def __hash__(self):
>         return hash(tuple(self.items()))
>     def __getattr__(self, name):
>         return getattr(self.__proxy, name)
>     def __getitem__(self, key):
>         return self.__proxy[key]
>     def __repr__(self):
>         return "%s(%r)" % (type(self).__name__, dict(self))
>
>
> --
> Steve
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20181016/c6a831bb/attachment.html>


More information about the Python-ideas mailing list