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