Like __getattr__ but with args and kwargs as well
MRAB
python at mrabarnett.plus.com
Fri May 28 14:42:45 EDT 2010
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?
>
Here's a way (mis)using a decorator (written in Python 3):
def locate(func):
def lookup(self, user):
for auth in self.authorizers:
if auth.has_user(user):
return getattr(auth, func.__name__)()
return ""
return lookup
class Authorizer:
def __init__(self, user):
self.user = user
def has_user(self, user):
return self.user == user
def get_home(self):
return "{}-HOME".format(self.user)
def get_password(self):
return "{}-PASSWORD".format(self.user)
class MixedAuthorizer:
def __init__(self, *authorizers):
self.authorizers = authorizers
# The following methods are used only as placeholders.
@locate
def get_home(self): pass
@locate
def get_password(self): pass
a1 = Authorizer("USER1")
a2 = Authorizer("USER2")
m = MixedAuthorizer(a1, a2)
print(m.get_home("USER1"))
print(m.get_password("USER2"))
More information about the Python-list
mailing list