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.__setitem__('a', 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