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

Reply via email to