Thanks. --- *Zaur Shibzukhov*
2015-03-17 22:48 GMT+03:00 Brett Cannon <br...@python.org>: > > > On Tue, Mar 17, 2015 at 3:46 PM Zaur Shibzukhov <szp...@gmail.com> wrote: > >> So in such cases it should not subclassed `dict`, but >> `collections.MutableMapping`, for example? >> > > Yes (see the comment at > https://hg.python.org/cpython/file/22a0c925a7c2/Objects/dictobject.c#l2003 > ). > > -Brett > > >> >> --- >> *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