<div class="gmail_quote"><div class="gmail_quote"><div class="im">On 21 August 2012 16:19, Oscar Benjamin <span dir="ltr"><<a href="mailto:oscar.benjamin@bristol.ac.uk" target="_blank">oscar.benjamin@bristol.ac.uk</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><p><br>
On Aug 21, 2012 3:42 PM, "Massimo DiPierro" <<a href="mailto:massimo.dipierro@gmail.com" target="_blank">massimo.dipierro@gmail.com</a>> wrote:<br>
><br>
> Thanks again Oscar. I cannot do that. I have tight constraints. I am not at liberty to modify the code that uses the class. The exposed API cannot change including a.x, dict(a), is isinstance(a,dict).<br>
><br>
> My goal it so change the definition of this class to make it faster.<br>
><br>
> Where is in the Python source code is the casting to dict defined? Where can I try understand what it does?</p>
</div><p>help(dict)</p>
<p>There is no cast, there is only the dict constructor. If the dict constructor finds a dict instance (including from a subclass) then it will efficiently create the new dict from the old dict's underlying data without calling your methods. If you want dict(a) and isinstance(dict) to work them you need to tell the dict superclass to store the data using dict.__setitem__.</p>
<p>You have three options:<br>
1) use SlowStorage<br>
2) duplicate the data in self and self.__dict__ (this will probably end up slowing down FastStorage)<br>
3) change the requirement to isinstance(Mapping)</p><span><font color="#888888">
<p>Oscar</p></font></span></blockquote></div><div>Okay, there is a way to solve your problem:</div><div><br></div><div><div>>>> class Storage(dict):</div><div>... def __init__(self, *args, **kwargs):</div><div>
... dict.__init__(self, *args, **kwargs)</div>
<div>... self.__dict__ = self</div><div>...</div><div>>>> s = Storage()</div><div>>>> s</div><div>{}</div><div>>>> s.x = 1</div><div>>>> s</div><div>{'x': 1}</div><div>
>>> dict(s)</div>
<div>{'x': 1}</div><div>>>> isinstance(s, dict)</div><div>True</div></div><div><br></div><div>But it's a stupid idea unless you know that the keys of your dict will *never* have any of the following values:</div>
<div><br></div><div><div>>>> dir({})</div><div>['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values', 'viewitems', 'viewkeys', 'viewvalues']</div>
</div><div><br></div><div>To see what goes wrong:</div><div><br></div><div><div>>>> s['items'] = [1,2,3]</div><div>>>> s.items()</div><div class="im"><div>Traceback (most recent call last):</div>
<div> File "<stdin>", line 1, in <module></div>
</div><div>TypeError: 'list' object is not callable</div></div><span class="HOEnZb"><font color="#888888"><div><br></div><div>Oscar</div><div><br></div></font></span></div>
</div><br>