Single and double asterisks preceding variables in function arguments

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Stephen Boulet

    #1

    Single and double asterisks preceding variables in function arguments

    I've run across code like "myfunction (x, *someargs, **someotherargs )",
    but haven't seen documentation for this.

    Can someone fill me in on what the leading * and ** do? Thanks.

    Stephen
  • anton muhin

    #2
    Re: Single and double asterisks preceding variables in function arguments

    Stephen Boulet wrote:[color=blue]
    > I've run across code like "myfunction (x, *someargs, **someotherargs )",
    > but haven't seen documentation for this.
    >
    > Can someone fill me in on what the leading * and ** do? Thanks.
    >
    > Stephen[/color]

    See item 7.5 in Language Reference. In short: * declaries list of
    additional parameters, while ** declares map of additional parameters.
    Try somehting like:

    def foo(*params): print params

    and

    def bar(**params): print params

    to find out details.

    regards,
    anton.

    Comment

    • Duncan Booth

      #3
      Re: Single and double asterisks preceding variables in function arguments

      anton muhin <antonmuhin@ram bler.ru> wrote in news:bv3gdg$ms0 sn$1@ID-
      217427.news.uni-berlin.de:
      [color=blue]
      > Stephen Boulet wrote:[color=green]
      >> I've run across code like "myfunction (x, *someargs, **someotherargs )",
      >> but haven't seen documentation for this.
      >>
      >> Can someone fill me in on what the leading * and ** do? Thanks.
      >>
      >> Stephen[/color]
      >
      > See item 7.5 in Language Reference. In short: * declaries list of
      > additional parameters, while ** declares map of additional parameters.
      > Try somehting like:
      >
      > def foo(*params): print params
      >
      > and
      >
      > def bar(**params): print params
      >
      > to find out details.[/color]

      I may be wrong, but I think the OP was asking about calling functions
      rather than defining them. The '*' and '**' before arguments in function
      calls are described in section 5.3.4 of the language reference but, so far
      as I know, isn't explained clearly in any of the more 'user level' text.
      There is a brief mention in the library reference under the documention of
      'apply'.

      In a call of the form:

      myfunction(x, *someargs, **someotherargs )

      the sequence 'someargs' is used to supply a variable number of additional
      positional arguments. 'someotherargs' should be a dictionary and is used to
      supply additional keyword arguments.

      Comment

      • Stephen Boulet

        #4
        Re: Single and double asterisks preceding variables in function arguments

        anton muhin wrote:
        [color=blue]
        > Stephen Boulet wrote:
        >[color=green]
        >> I've run across code like "myfunction (x, *someargs, **someotherargs )",
        >> but haven't seen documentation for this.
        >>
        >> Can someone fill me in on what the leading * and ** do? Thanks.
        >>
        >> Stephen[/color]
        >
        >
        > See item 7.5 in Language Reference. In short: * declaries list of
        > additional parameters, while ** declares map of additional parameters.
        > Try somehting like:
        >
        > def foo(*params): print params
        >
        > and
        >
        > def bar(**params): print params
        >
        > to find out details.
        >
        > regards,
        > anton.[/color]

        <<
        a={'c1':'red',' c2':'blue','c3' :'fusia'}
        def bar(**params):
        .....for k in params.keys():
        .........print k, params[k]
        bar(a)
        Traceback (most recent call last):
        File "<input>", line 1, in ?
        TypeError: bar() takes exactly 0 arguments (1 given)[color=blue][color=green]
        >>[/color][/color]

        Why does bar take zero arguments?

        Hmm, but:

        <<
        def bar2(*params,** moreparams):
        .....print "params are ", params,'\n'
        .....for k in moreparams.keys ():
        .........print k, moreparams[k]
        .....print "moreparams are ", moreparams

        bar2(range(3),a ,)
        params are ([0, 1, 2], {'c3': 'fusia', 'c2': 'blue', 'c1': 'red'})

        moreparams are {}[color=blue][color=green]
        >>[/color][/color]

        I think I've got the *params argument down (you just get the whole
        argument list), but I'm still not getting the **moreparams ...

        Stephen

        Comment

        • Peter Otten

          #5
          Re: Single and double asterisks preceding variables in function arguments

          Stephen Boulet wrote:
          [color=blue]
          > <<
          > a={'c1':'red',' c2':'blue','c3' :'fusia'}
          > def bar(**params):
          > ....for k in params.keys():
          > ........print k, params[k]
          > bar(a)
          > Traceback (most recent call last):
          > File "<input>", line 1, in ?
          > TypeError: bar() takes exactly 0 arguments (1 given)[color=green][color=darkred]
          > >>[/color][/color]
          >
          > Why does bar take zero arguments?[/color]

          The error message is not as clear as it should should be. bar() takes 0
          mandatory, 0 positional and an arbitrary number of keyword arguments, e.
          g.:
          [color=blue][color=green][color=darkred]
          >>> def bar(**params):[/color][/color][/color]
          .... print params
          ....[color=blue][color=green][color=darkred]
          >>> bar(color="blue ", rgb=(0,0,1), name="sky")[/color][/color][/color]
          {'color': 'blue', 'rgb': (0, 0, 1), 'name': 'sky'}

          That's the standard way of passing optional keyword arguments, but you can
          also pass them as a dictionary preceded by **:
          [color=blue][color=green][color=darkred]
          >>> adict = {'color': 'blue', 'rgb': (0, 0, 1), 'name': 'sky'}
          >>> bar(**adict)[/color][/color][/color]
          {'color': 'blue', 'rgb': (0, 0, 1), 'name': 'sky'}

          This is useful, if you want to compose the argument dict at runtime, or pass
          it through to a nested function.
          [color=blue]
          >
          > Hmm, but:
          >
          > <<
          > def bar2(*params,** moreparams):
          > ....print "params are ", params,'\n'
          > ....for k in moreparams.keys ():
          > ........print k, moreparams[k]
          > ....print "moreparams are ", moreparams[/color]

          bar2() accepts 0 mandatory, as many positional and keyword arguments as you
          like. For the expected result, try
          [color=blue][color=green][color=darkred]
          >>> def bar2(*args, **kwd):[/color][/color][/color]
          .... print args
          .... print kwd
          ....[color=blue][color=green][color=darkred]
          >>> bar2(1,2,3)[/color][/color][/color]
          (1, 2, 3)
          {}[color=blue][color=green][color=darkred]
          >>> bar2(1, name="sky", color="blue")[/color][/color][/color]
          (1,) # tuple of optional positional args
          {'color': 'blue', 'name': 'sky'} # dict of optional keyword args[color=blue][color=green][color=darkred]
          >>>[/color][/color][/color]

          And now a bogus example that shows how to compose the arguments:
          [color=blue][color=green][color=darkred]
          >>> def bar3(x, *args, **kwd):[/color][/color][/color]
          .... print "x=", x
          .... print "args=", args
          .... print "kwd=", kwd
          .... if "terminate" not in kwd:
          .... kwd["terminate"] = None # avoid infinite recursion
          .... bar3(x*x, *args + ("alpha",), **kwd)
          ....[color=blue][color=green][color=darkred]
          >>> bar3(2, "beta", color="blue")[/color][/color][/color]
          x= 2
          args= ('beta',)
          kwd= {'color': 'blue'}
          x= 4
          args= ('beta', 'alpha')
          kwd= {'color': 'blue', 'terminate': None}[color=blue][color=green][color=darkred]
          >>>[/color][/color][/color]

          To further complicate the matter, a mandatory arg may also be passed as a
          keyword argument:

          bar3(x=2, color="blue") # will work, args is empty
          bar("beta", # will not work; both "beta" and 2 would be bound to x
          # and thus create a conflict
          x=2, color="blue")


          Peter

          Comment

          • Eric Amick

            #6
            Re: Single and double asterisks preceding variables in function arguments

            On Mon, 26 Jan 2004 09:51:02 -0600, Stephen Boulet
            <stephendotboul et@motorola_._c om> wrote:
            [color=blue]
            >I've run across code like "myfunction (x, *someargs, **someotherargs )",
            >but haven't seen documentation for this.
            >
            >Can someone fill me in on what the leading * and ** do? Thanks.[/color]

            Try section 4.7.2 of the tutorial.

            --
            Eric Amick
            Columbia, MD

            Comment

            • Ben Finney

              #7
              Re: Single and double asterisks preceding variables in function arguments

              On Mon, 26 Jan 2004 20:15:22 -0500, Eric Amick wrote:[color=blue]
              > Try section 4.7.2 of the tutorial.[/color]

              Matter of fact, try the whole tutorial, beginning to end. It will
              answer many questions you haven't thought of yet.

              <http://www.python.org/doc/tut/>

              --
              \ "Those are my principles. If you don't like them I have |
              `\ others." -- Groucho Marx |
              _o__) |
              Ben Finney <http://bignose.squidly .org/>

              Comment

              • Aahz

                #8
                Re: Single and double asterisks preceding variables in function arguments

                In article <bv3gdg$ms0sn$1 @ID-217427.news.uni-berlin.de>,
                anton muhin <antonmuhin@ram bler.ru> wrote:[color=blue]
                >
                >See item 7.5 in Language Reference. In short: * declaries list of
                >additional parameters, while ** declares map of additional parameters.[/color]

                Actually, ``*`` forces creation of a tuple:
                [color=blue][color=green][color=darkred]
                >>> def foo(*bar):[/color][/color][/color]
                .... print type(bar)
                ....[color=blue][color=green][color=darkred]
                >>> l = [1,2,3]
                >>> foo(*l)[/color][/color][/color]
                <type 'tuple'>
                --
                Aahz (aahz@pythoncra ft.com) <*> http://www.pythoncraft.com/

                "The joy of coding Python should be in seeing short, concise, readable
                classes that express a lot of action in a small amount of clear code --
                not in reams of trivial code that bores the reader to death." --GvR

                Comment

                Working...