On 1 Apr, 10:57, Jonathan Fine <j.f...@open.ac.uk> wrote: > The idioms > def f(*args, **kwargs): > # Do something. > and > args = (1, 2, 3) > kwargs = dict(a=4, b=5) > g(*args, **kwargs) > are often useful in Python. > > I'm finding myself picking up /all/ the arguments and storing them for > later use (as part of a testing framework). So for me it would be nice > if I could write > def f(***allargs): > args, kwargs = allargs > # Continue as before. > > However, if we do this then 'args' in '*args' is misleading. So I'll > use 'sargs' (for sequence arguments) instead. > > I can now write, for a suitable class Args > args = Args(1, 2, 3, a=4, b=5) > g(***args) # Same as before. > sargs, kwargs = args > g(*sargs, **kwargs) # Same as before. > > Even better, now that Args is a class we can give it a method 'call' so that > args.call(g) > is equivalent to > g(***args) > which removes the need for the *** construct. > > This reminds me of functools.partial except, of course, we've fixed all > the arguments and left the passing of the function for later, whereas in > partial we fix the function and some of the arguments. > http://docs.python.org/library/functools.html#functools.partial > > My view are that > 1. Conceptually ***allargs is useful, but an Args class would be more > useful (not that it need be either-or). > > 2. If Args were built in , there could be performance benefits. > > 3. It's clearer to write > def(*seqargs, **kwargs): > than > def(*args, **kwargs): > > 4. When the Args class is used a lot, one might welcome > def(***args): > # Do something with args. > as a shortcut (and minor speedup) for > def(*seqargs, **kwargs): > args = Args(*seqargs, **kwargs) > # Do something with args. > > I look forward to your comments on this. > > -- > Jonathan
I'm not sure this'll catch on, it'll be interesting to see other comments. However, I believe you can get the behaviour you desire something like: import inspect class AllArgs(object): def __init__(self, func): self._func = func self._spec = inspect.getargspec(func) self._nposargs = len(self._spec.args) def __call__(self, *args, **kwdargs): self._func.func_globals['Args'] = (args[self._nposargs:], kwdargs) return self._func(*args[:self._nposargs]) @AllArgs def test(): print Args @AllArgs def test2(a, b): print a, b, Args test(1, 2, 3, 4, 5, a=3, b=5) test2(1, 2, 3, 4, 5, c=7) Done quickly, probably buggy, but does provide 'Args', but without further work swallows any *'s and **'s and might ignore defaults (hideously untested) hth Jon. -- http://mail.python.org/mailman/listinfo/python-list