Further inspired by the Routes submapper idea (see DRY up your routes) here’s a generic proxy object that collects arguments repeated across method calls:
class Params(object):
def __init__(self, obj, *args, **kwargs):
self.__obj = obj
self.__args = args
self.__kwargs = kwargs
def __getattr__(self, name):
try:
attr = getattr(self.__obj, name)
if callable(attr):
# Target attr is callable; return another that
# will sneak in our remembered args
def wrapped_method(*args, **kwargs):
return attr(*(self.__args + args),
**dict(self.__kwargs, **kwargs))
return wrapped_method
else:
# Plain old attribute
return attr
except AttributeError:
# self.foo(bar, *args, **kwargs)
# -> scope(self, foo=bar, *args, **kwargs)
def wrapped_scope(*args, **kwargs):
return Params(self, *args[1:],
**dict({name: args[0]}, **kwargs))
return wrapped_scope
def __enter__(self):
return self
def __exit__(self, type, value, tb):
pass
params = Params
You can use it submapper-style (with or without the ‘with‘ syntax), collecting arbitrary args and kwargs as follows:
with params(mapper, controller='entries') as entries:
entries.connect(...)
entries.connect(...)
...
Here controller='entries' gets included in each method call to the underlying mapper.
Equivalently, it supports a “fluent” or DSL-ish style where named parameters are transfomed into (chainable) methods:
m = params(mapper)
with m.controller('entries') as entries:
entries.connect(...)
entries.connect(...)
...
Of course the Routes API (in the dev version at least) already has submappers and param makes a poor substititute, but as tool for reducing duplication elsewhere it may yet prove useful.
Tags: python