Q: We have *args and **kwargs. Woud ***allargs be useful?

Discussion in 'Python' started by Jonathan Fine, Apr 1, 2010.

  1. 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
     
    Jonathan Fine, Apr 1, 2010
    #1
    1. Advertising

  2. Jonathan Fine

    Jon Clements Guest

    Re: Q: We have *args and **kwargs. Woud ***allargs be useful?

    On 1 Apr, 10:57, Jonathan Fine <> 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.
     
    Jon Clements, Apr 1, 2010
    #2
    1. Advertising

  3. Re: Q: We have *args and **kwargs. Woud ***allargs be useful?

    Jon Clements wrote:

    > 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)


    Thank you for your interest, Jon.

    According to http://docs.python.org/library/inspect.html we have that
    func_globals is the global namespace in which this function was defined.

    Hence we have
    >>> def f(): pass

    ....
    >>> f.func_globals is globals()

    True
    >>> f.func_globals ['x'] = 3
    >>> x

    3
    >>>


    I don't yet understand what your code is intended to do, but I'm fairly
    sure you're not wishing to 'monkey-patch' a global namespace of a module.

    --
    Jonathan
     
    Jonathan Fine, Apr 1, 2010
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Eelco Hoogendoorn

    Verbose and flexible args and kwargs syntax

    Eelco Hoogendoorn, Dec 11, 2011, in forum: Python
    Replies:
    1
    Views:
    252
    Steven D'Aprano
    Dec 11, 2011
  2. Eelco Hoogendoorn

    Verbose and flexible args and kwargs syntax

    Eelco Hoogendoorn, Dec 11, 2011, in forum: Python
    Replies:
    0
    Views:
    162
    Eelco Hoogendoorn
    Dec 11, 2011
  3. Eelco Hoogendoorn

    Verbose and flexible args and kwargs syntax

    Eelco Hoogendoorn, Dec 11, 2011, in forum: Python
    Replies:
    0
    Views:
    191
    Eelco Hoogendoorn
    Dec 11, 2011
  4. Eelco Hoogendoorn

    Verbose and flexible args and kwargs syntax

    Eelco Hoogendoorn, Dec 11, 2011, in forum: Python
    Replies:
    88
    Views:
    1,065
    Grant Edwards
    Dec 17, 2011
  5. Eelco Hoogendoorn

    Verbose and flexible args and kwargs syntax

    Eelco Hoogendoorn, Dec 11, 2011, in forum: Python
    Replies:
    0
    Views:
    165
    Eelco Hoogendoorn
    Dec 11, 2011
Loading...

Share This Page