On Tue, Mar 17, 2015 at 3:29 PM Zaur Shibzukhov <szp...@gmail.com> wrote:
> Yes... But I expected that dict constructor will use `__getitem__` or > `items` method of MyDict instance in order to retrieve items of the MyDict > instance during construction of the dict instance... Instead it interpreted > MyDict instance as the dict instance during construction of new dict.This > exactly caused my confusion. > It's because you subclassed dict. Copying is optimized to skip over using the methods you listed when the object is a dict and so we know the structure of the object at the C level. You can look at https://hg.python.org/cpython/file/22a0c925a7c2/Objects/dictobject.c#l1997 to see the actual code. -Brett > > --- > *Zaur Shibzukhov* > > > 2015-03-17 22:12 GMT+03:00 Brett Cannon <br...@python.org>: > >> >> >> On Tue, Mar 17, 2015 at 3:05 PM Zaur Shibzukhov <szp...@gmail.com> wrote: >> >>> Hello! >>> >>> In order to explain, let define subclass of dict: >>> >>> class Pair: >>> def __init__(self, key, val): >>> self.key = key >>> self.val = val >>> >>> class MyDict(dict): >>> # >>> def __init__(self, *args, **kwds): >>> if len(args) > 1: >>> raise TypeError('Expected at most 1 arguments, but got %d' % >>> len(args)) >>> >>> for key, val in args[0]: >>> self[key] = val >>> >>> for key, val in kwds.items(): >>> self[key] = val >>> >>> def __getitem__(self, key): >>> pair = dict.__getitem__(key) >>> return pair.value >>> >>> def __setitem__(self, key, val): >>> if key in self: >>> pair = dict.__getitem__(key) >>> pair.value = value >>> else: >>> pair = Pair(key, val) >>> dict.__setitem__(self, key, pair) >>> >>> def values(self): >>> for key in self: >>> p = dict.__getitem__(self, key) >>> yield p.value >>> >>> def items(self): >>> for key, p in dict.__iter__(self): >>> yield p.key, p.value >>> >>> >>> The simple test give me strange result: >>> >>> >>> d = MyDict([('a', 1), ('b', 2), ('c', 3)]) >>> >>> dict(d) >>> {'a': <__main__.Pair at 0x104ca9e48>, >>> 'b': <__main__.Pair at 0x104ca9e80>, >>> 'c': <__main__.Pair at 0x104ca9eb8>} >>> >>> instead of {'a':1, 'b':2, 'c':3}. >>> >>> >>> Is this right behavior of the dict? >>> >> >> Yes because in your __setitem__ call you are storing the value as the >> Pair. So when dict prints its repr it prints the key and value, and in this >> case the value is a Pair. >> > >
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com