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.

How could I now it:

  1 import collections
  2 import functools
  3 import itertools
  4
  5
  6 def verbose_func(func):
  7     'Function decorator that makes a function "verbose"'
  8
  9     @functools.wraps(func, assigned=('__name__', '__doc__'))
 10     def func_wrapper(*args, **kwargs):
 11         iargs = (map(str, args))
 12         ikwargs = ('{0}={1}'.format(key, value)
 13                    for key, value in kwargs.items())
 14         func_args = ', '.join(itertools.chain(iargs, ikwargs))
 15         print('{0}({1})'.format(func.__name__, func_args))
 16         return func(*args, **kwargs)
 17
 18     return func_wrapper
 19
 20
 21 def verbose_cls(base):
 22     'Class decorator that makes callable attributes "verbose"'
 23
 24     quiet = ('__new__', '__repr__', '__str__')
 25
 26     def cls_wrapper(cls):
 27         for name in vars(base):
 28             attr = getattr(cls, name)
29 if isinstance(attr, collections.Callable) and name not in quiet:
 30                 setattr(cls, name, verbose_func(attr))
 31         return cls
 32
 33     return cls_wrapper
 34
 35
 36 @verbose_cls(dict)
 37 class VerboseDict(dict):
 38     pass
 39
 40
 41 @verbose_cls(int)
 42 class MyInt(int):
 43
 44     @verbose_func
 45     def __iadd__(self, other):
 46         int.__add__(self, other)  # can do something more interesting
 47
 48
 49 if __name__ == '__main__':
 50     d = VerboseDict()
 51
 52     print("d['a'] = 3")
 53     d['a'] = MyInt(3)
 54
 55     print("d['a'] += 3")
 56     d['a'] += MyInt(3)

*j

--
Jan Kaliszewski (zuo) <z...@chopin.edu.pl>
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to