Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #109748
| From | Nagy László Zsolt <gandalf@shopzeus.com> |
|---|---|
| Newsgroups | comp.lang.python |
| Subject | Re: UserList - which methods needs to be overriden? |
| Date | 2016-06-09 15:55 +0200 |
| Message-ID | <mailman.115.1465480515.2306.python-list@python.org> (permalink) |
| References | (1 earlier) <njbdhk$pv2$1@ger.gmane.org> <917ca9c4-aef1-6681-ec70-62de8916117d@shopzeus.com> <njbp5d$mn9$1@ger.gmane.org> <7cdb398f-b3f2-9a3c-b444-2229f8496e2f@shopzeus.com> <13f5d47e-39e2-76ce-e0c6-195a4bd25e7b@shopzeus.com> |
> @wrap_notify('remove', 'clear', 'append', 'insert', 'sort'):
> class ObservableList(ObservableCollection, list):
> pass
>
> I just can't find out the right syntax.
>
>
All right, this is working.
from contextlib import contextmanager
class ObservableCollection:
@contextmanager
def notify(cls):
print("notify before change")
yield
print("notify after change")
def wrap_notify(cls, basecls, method_names):
for method_name in method_names:
orig = getattr(basecls, method_name)
def modified(self, *args, **kwargs):
with self.notify(): return orig(self,*args,**kwargs)
setattr(cls, method_name, modified)
return cls
class ObservableDict(ObservableCollection, dict):
__slots__ = []
wrap_notify(ObservableDict, dict, ['update', '__delitem__',
'__setitem__']) # many others...
class ObservableList(ObservableCollection, list):
__slots__ = []
wrap_notify(ObservableList, list, ['append', 'pop']) # many others...
d = ObservableDict()
d[1] = 2
print(d)
But I'm still not 100% satisfied. wrap_notify is not a class decorator.
Is there a way to make a class decorator that gets the class as its
first parameter? It would be very nice:
def wrap_notify(cls, method_names):
class Wrapped(cls):
pass
for method_name in method_names:
orig = getattr(Wrapped, method_name)
def modified(self, *args, **kwargs):
with self.notify(): return orig(self,*args,**kwargs)
setattr(cls, method_name, modified)
return Wrapped
@wrap_notify(['update', '__delitem__', '__setitem__']) # many others...
class ObservableDict(ObservableCollection, dict):
__slots__ = []
@wrap_notify(['append', 'pop']) # many others...
class ObservableList(ObservableCollection, list):
__slots__ = []
And finally: is this Pythonic, or a horrible mess? Would it be better to
duplicate the body of each method one by one?
Back to comp.lang.python | Previous | Next | Find similar | Unroll thread
Re: UserList - which methods needs to be overriden? Nagy László Zsolt <gandalf@shopzeus.com> - 2016-06-09 15:55 +0200
csiph-web