2010/5/28 Peter Otten <__pete...@web.de>: > Giampaolo Rodolà wrote: > >> I know, the title doesn't say much, but I had no better ideas. =) >> I have a class within a serie of redundant methods, which looks like this: >> >> class MixedAuthorizer: >> >> def __init__(self, *args): >> # expected a list of class instances >> self.authorizers = args >> >> def get_home(self, user): >> for auth in self.authorizers: >> if not auth.has_user(user): >> continue >> return auth.get_home(user) >> return "" >> >> def get_password(self, user): >> for auth in self.authorizers: >> if not auth.has_user(user): >> continue >> return auth.get_password(user) >> return "" >> >> # follows a long list of get_* methods as above >> ... >> >> >> Considering that I always do the same thing (iterate over a list of >> objects -> call obj.has_user() -> call obj.get_*()) I would like to >> know if there's a more compact way to do that. >> What I basically need is something like __getattr__ but which provides >> the arguments and eventually the keyword arguments a method has been >> called with, other than just its name. >> Actually I'm not even sure whether Python can reach such a level of >> dynamism but I wanted to give it a try anyway. >> Is there a way to do such a thing? > > Yes, and for the above example it is easier to implement than you think: > > class MA(object): > def __init__(self, authorizers): > self.authorizers = authorizers > def __getattr__(self, name): > def get(self, user): > for auth in self.authorizers: > if auth.has_user(user): > return getattr(auth, name)(user) > return get.__get__(self) > > You can modify it to pass along arbitrary keyword arguments: > > class MA(object): > def __init__(self, authorizers): > self.authorizers = authorizers > def __getattr__(self, name): > def get(self, **kw): > for auth in self.authorizers: > if auth.has_user(kw["user"]): > return getattr(auth, name)(**kw) > return get.__get__(self) > > Peter > -- > http://mail.python.org/mailman/listinfo/python-list >
Thanks, this has been helpful. I managed to write this monster: =) class MixedAuthorizer(object): def __init__(self, *authorizers): self.authorizers = authorizers def __getattr__(self, name): def get(self, user, *args, **kwargs): for auth in self.authorizers: if auth.has_user(user): method = getattr(auth, name) return method(user, *args, **kwargs) # if we reached this point no user was found if name == "validate_authentication": return False if name.startswith("get"): return "" if name.startswith("has"): return False return get.__get__(self) --- Giampaolo http://code.google.com/p/pyftpdlib http://code.google.com/p/psutil -- http://mail.python.org/mailman/listinfo/python-list