Overriding iadd for dictionary like objects

Aahz aahz at pythoncraft.com
Wed Sep 2 05:24:45 CEST 2009


In article <7f82416a-53be-41b3-9503-1492454cc32c at upsg2000gro.googlegroups.com>,
RunThePun  <ubershmekel at gmail.com> wrote:
>On Sep 1, 3:00=A0am, a... at pythoncraft.com (Aahz) wrote:
>> In article <b11a8a0e-03ca-41c9-b0d0-c5180b6a2... at p15g2000vbl.googlegroups=
>.com>,
>> RunThePun =A0<ubershme... at gmail.com> wrote:
>>>On Aug 30, 10:33=3DA0pm, a... at pythoncraft.com (Aahz) wrote:
>>>> In article <e09276e8-8152-4002-8366-4c12705a8... at l35g2000vba.googlegro=
>ups=3D
>>>.com>,
>>>> RunThePun =3DA0<ubershme... at gmail.com> wrote:
>>
>>>>>I made a DictMixin where the keys are filenames and the values are the
>>>>>file contents. It was very simple and easy to do thanks to DictMixin.
>>
>>>>>For example this code writes "abc" in a file named "temp.txt" and
>>>>>prints the contents of the file named "swallow", these files are
>>>>>looked up/created/deleted in the directory "spam":
>>>>>>>> d =3D3D3D FilesDict('spam')
>>>>>>>> d['temp.txt'] =3D3D3D 'abc'
>>>>>>>> print(d['swallow'])
>>
>>>>>My problem arose when I wanted to append a string to a file which
>>>>>using open(..., 'ab') would have been miles more efficient because I
>>>>>wouldn't have to read the entire file (__getitem__) and then write the
>>>>>entire file back (__setitem__). The files are expected to be as big as
>>>>>600 KB which will be appended 30 bytes at a time about 3 times a
>>>>>second. Performance-wise the system would probably work without open
>>>>>(..., 'ab') but it would be a real thrashing so the current solution
>>>>>uses a method "AddTo" as Robert suggested, sacrificing the neat
>>>>>getitem/setitem syntax.
>>
>>>> You can do mostly what you want, I think, by having __setitem__()
>>>> convert string values into FileProxy() objects that have an appropriat=
>e
>>>> __iadd__() method. =3DA0That brings a whole new set of problems, of co=
>urse.
>>
>>>I'm guessing you meant __getitem__, which is what Jan Kaliszewski
>>>suggested, but as you noted, would be a bit cumbersome in this case.
>>
>> Actually, what I meant was __setitem__. =A0The idea is that you create th=
>e
>> proxy item when you add the data to the dict (wrapping the original
>> data), and the proxy has an __iadd__ method, which would allow you to do
>> the file append.
>
>But you do mean that __getitem__ would return a wrapped object as
>well, right? Otherwise I don't see how the iadd would be relevant
>because:
>       d['a'] +=3D 3
>is equivalent to:
>       d.__setitem__('a', d.__getitem__('a').__iadd__(3))

The __getitem__ returns the proxy object created by the first __setitem__
when you did

d['a'] = 'something'

The __iadd__ of the proxy object returns self, so it's the same object,
which means that the second __setitem__ (called by +=) can check to see
that you already have a proxy object and it does not need to rewrap it.

If this still doesn't make sense, I suggest you go ahead and try the
experiment to prove that it does work.  ;-)
-- 
Aahz (aahz at pythoncraft.com)           <*>         http://www.pythoncraft.com/

"Look, it's your affair if you want to play with five people, but don't
go calling it doubles."  --John Cleese anticipates Usenet



More information about the Python-list mailing list