Re: Overriding iadd for dictionary like objects

2009-09-01 Thread RunThePun
On Sep 1, 3:00 am, a...@pythoncraft.com (Aahz) wrote:
 In article 
 b11a8a0e-03ca-41c9-b0d0-c5180b6a2...@p15g2000vbl.googlegroups.com,





 RunThePun  ubershme...@gmail.com wrote:
 On Aug 30, 10:33=A0pm, a...@pythoncraft.com (Aahz) wrote:
  In article e09276e8-8152-4002-8366-4c12705a8...@l35g2000vba.googlegroups=
 .com,
  RunThePun =A0ubershme...@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 =3D3D FilesDict('spam')
  d['temp.txt'] =3D3D '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 appropriate
  __iadd__() method. =A0That brings a whole new set of problems, of course.

 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__.  The idea is that you create the
 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.
 --
 Aahz (a...@pythoncraft.com)           *        http://www.pythoncraft.com/

 I support family values -- Addams family values --www.nancybuttons.com

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'] += 3
is equivalent to:
   d.__setitem__('a', d.__getitem__('a').__iadd__(3))
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Overriding iadd for dictionary like objects

2009-08-31 Thread RunThePun
On Aug 30, 10:33 pm, a...@pythoncraft.com (Aahz) wrote:
 In article 
 e09276e8-8152-4002-8366-4c12705a8...@l35g2000vba.googlegroups.com,





 RunThePun  ubershme...@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 =3D FilesDict('spam')
  d['temp.txt'] =3D '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 appropriate
 __iadd__() method.  That brings a whole new set of problems, of course.
 --
 Aahz (a...@pythoncraft.com)           *        http://www.pythoncraft.com/

 I support family values -- Addams family values --www.nancybuttons.com

I'm guessing you meant __getitem__, which is what Jan Kaliszewski
suggested, but as you noted, would be a bit cumbersome in this case.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Overriding iadd for dictionary like objects

2009-08-30 Thread RunThePun
On Aug 29, 1:58 pm, Carl Banks pavlovevide...@gmail.com wrote:
 On Aug 28, 10:37 pm, Joshua Judson Rosen roz...@geekspace.com wrote:





  Carl Banks pavlovevide...@gmail.com writes:

   On Aug 28, 2:42 pm, Terry Reedy tjre...@udel.edu wrote:

Carl Banks wrote:
 I don't think it needs a syntax for that, but I'm not so sure a method
 to modify a value in place with a single key lookup wouldn't
 occasioanally be useful.

Augmented assignment does that.

   Internally uses two lookups, one for getting, and one for setting.

   I think this is an unavoidable given Python's semantics.  Look at
   the traceback:

def x():
   ...     d['a'] += 1
   ...
dis.dis(x)
     2           0 LOAD_GLOBAL              0 (d)
                 3 LOAD_CONST               1 ('a')
                 6 DUP_TOPX                 2
                 9 BINARY_SUBSCR

  OK, there's one lookup, but...

                10 LOAD_CONST               2 (1)
                13 INPLACE_ADD
                14 ROT_THREE
                15 STORE_SUBSCR
                16 LOAD_CONST               0 (None)
                19 RETURN_VALUE

  ... I don't see anything in there that retrieves the value a second time

 STORE_SUBSCR has to look up the position in the hash table to store
 the value, hence the second lookup.

 As a workaround, if lookups are expensive,

But they are not. Because (C)Python is heavily based on dict name lookup
for builtins and global names and attributes, as well as overt dict
lookup, must effort has gone into optimizing dict lookup.

   The actual lookup algorithm Python dicts use is well-optimized, yes,
   but the dict could contain keys that have expensive comparison and
   hash-code calculation, in which case lookup is going to be slow.

  I'll like the originator correct me if I've made a mistake, but I read
  lookup as actually meaning lookup, not value-comparison.

 This has nothing to do with value comparison.  I was talking about key
 comparison, which happens when looking up a position in a hash table.
 I was the first person to use the word lookup in this thread and I
 specifically meant hash-table position lookup.

  At least in part because the question, as it was posed, specifically
  related to a wrapper-class (providing a mapping (dict like) interface)
  around a database of some sort other than Python's dict class per se.

  How do the details of Python's native dict-type's internal (hashtable)
  algorithm matter when they're explicitly /not/ being used?

 Well it doesn't apply specifically to the OP's problem.  I changed the
 topic a bit by making it specific to dicts.  Is that ok with you?  Was
 that not allowed?

 The OP can add a method like apply_to_value to his own class, but one
 can't do that for dicts.  Ergo why something like apply_to_value()
 would be useful enough in rare circumstances where lookup is very slow
 to merit a moments consideration before being rejected.

 (If dict did have a method like that, the OP would at least know which
 method to override.)

 Carl Banks

First of all I'd like to say thanks for this discussion, you guys are
awesome.

I probably should have explained my problem better to begin with and I
apologize for that. So now I'll start from the top:

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 = FilesDict('spam')
 d['temp.txt'] = 'abc'
 print(d['swallow'])

This was very convenient for me because I wanted to use a simple DB
which could be read and edited by shell scripts and non-pythonistas,
without the heavy ORM. Also, if in the future an online full featured
DB would be needed, I could easily convert the DictMixin methods.  So
up to here I had a good solution.

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.

Just so I don't leave out any information, I actually also made a
DirectoryDict for having multiple 'tables'. In this DictMixin, keys
are directory names and values are FilesDict instances. So to write
European or African to the file /root/tmp/velocity one would be
just:
 d = DirectoryDict(/root)
 d[tmp][velocity] = European or African

So now I hope it's clearer why and how I wanted a special
__item_iadd__ for the dictionary syntax,

RunThePun

Re: Overriding iadd for dictionary like objects

2009-08-27 Thread RunThePun
On Aug 27, 6:58 am, Robert Kern robert.k...@gmail.com wrote:
 On 2009-08-26 20:00 PM, Jan Kaliszewski wrote:





  27-08-2009 o 00:48:33 Robert Kern robert.k...@gmail.com wrote:

  On 2009-08-26 17:16 PM, RunThePun wrote:
  I'd like to build a database wrapper using DictMixin and allow items
  to be appended by my own code. The problem is += is always understood
  as setitem and getitem plainly.

  d = MyDict()
  d['a'] = 1

  # this is the problem code that's I'd like to override. It's always
  setitem('a', getitem('a') + 3)
  d['a'] += 3
  # i wanted to do something like my own 'appenditem' function which for
  example could be useful if getitem is an expensive operation which can
  be avoided.

  I hope that was clear enough of a request, it's really late at night
  here...

  I'm sorry, this is just part of the syntax of Python. You cannot
  override it.

  Though
  d['a'] = 3
  is equivalent to:
  d.__setitem__('a', 3)

  The
  d['a'] += 3
  *is not* equivalent to:
  d.__setitem__('a', d.__getitem__('a') + 3)
  *but is* equivalent to:
  d.__getitem__('a').__iadd__(3)

  Then you can override __getitem__() of MyDict in such a way that it
  returns prepared (wrapped) object with overriden __iadd__() as you
  want to.

 You could, but then you will almost certainly run into problems using the
 wrapped object in places that really expect the true object.

 --
 Robert Kern

 I have come to believe that the whole world is an enigma, a harmless enigma
   that is made terrible by our own mad attempt to interpret it as though it 
 had
   an underlying truth.
    -- Umberto Eco

Exactly my problem Robert. I'm actually going to be using this dict
for storing and retrieving strings so wrapping str and replacing the
iadd would cause alot of craziness.

Anybody have any more ideas? I think python should/could havev a
syntax for overriding this behaviour, i mean, obviously the complexity
of supporting all operators with the getitem syntax could introduce
alot of clutter. But maybe there's an elegant solution out there...

---RP
-- 
http://mail.python.org/mailman/listinfo/python-list


Overriding iadd for dictionary like objects

2009-08-26 Thread RunThePun
I'd like to build a database wrapper using DictMixin and allow items
to be appended by my own code. The problem is += is always understood
as setitem and getitem plainly.

d = MyDict()
d['a'] = 1

# this is the problem code that's I'd like to override. It's always
setitem('a', getitem('a') + 3)
d['a'] += 3
# i wanted to do something like my own 'appenditem' function which for
example could be useful if getitem is an expensive operation which can
be avoided.

I hope that was clear enough of a request, it's really late at night
here...

thanks,

RunPun
-- 
http://mail.python.org/mailman/listinfo/python-list