So in such cases it should not subclassed `dict`, but `collections.MutableMapping`, for example?
--- *Zaur Shibzukhov* 2015-03-17 22:38 GMT+03:00 Brett Cannon <br...@python.org>: > > > 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