Can a variable number of arguments be passed to a function?

后端 未结 6 778
长发绾君心
长发绾君心 2020-11-22 00:32

In a similar way to using varargs in C or C++:

fn(a, b)
fn(a, b, c, d, ...)
相关标签:
6条回答
  • 2020-11-22 00:42

    Adding to unwinds post:

    You can send multiple key-value args too.

    def myfunc(**kwargs):
        # kwargs is a dictionary.
        for k,v in kwargs.iteritems():
             print "%s = %s" % (k, v)
    
    myfunc(abc=123, efh=456)
    # abc = 123
    # efh = 456
    

    And you can mix the two:

    def myfunc2(*args, **kwargs):
       for a in args:
           print a
       for k,v in kwargs.iteritems():
           print "%s = %s" % (k, v)
    
    myfunc2(1, 2, 3, banan=123)
    # 1
    # 2
    # 3
    # banan = 123
    

    They must be both declared and called in that order, that is the function signature needs to be *args, **kwargs, and called in that order.

    0 讨论(0)
  • 2020-11-22 00:43
    def f(dic):
        if 'a' in dic:
            print dic['a'],
            pass
        else: print 'None',
    
        if 'b' in dic:
            print dic['b'],
            pass
        else: print 'None',
    
        if 'c' in dic:
            print dic['c'],
            pass
        else: print 'None',
        print
        pass
    f({})
    f({'a':20,
       'c':30})
    f({'a':20,
       'c':30,
       'b':'red'})
    ____________
    

    the above code will output

    None None None
    20 None 30
    20 red 30
    

    This is as good as passing variable arguments by means of a dictionary

    0 讨论(0)
  • 2020-11-22 00:45

    Yes. You can use *args as a non-keyword argument. You will then be able to pass any number of arguments.

    def manyArgs(*arg):
      print "I was called with", len(arg), "arguments:", arg
    
    >>> manyArgs(1)
    I was called with 1 arguments: (1,)
    >>> manyArgs(1, 2, 3)
    I was called with 3 arguments: (1, 2, 3)
    

    As you can see, Python will unpack the arguments as a single tuple with all the arguments.

    For keyword arguments you need to accept those as a separate actual argument, as shown in Skurmedel's answer.

    0 讨论(0)
  • 2020-11-22 00:51

    Another way to go about it, besides the nice answers already mentioned, depends upon the fact that you can pass optional named arguments by position. For example,

    def f(x,y=None):
        print(x)
        if y is not None:
            print(y)
    

    Yields

    In [11]: f(1,2)
    1
    2
    
    In [12]: f(1)
    1
    
    0 讨论(0)
  • 2020-11-22 00:55

    If I may, Skurmedel's code is for python 2; to adapt it to python 3, change iteritems to items and add parenthesis to print. That could prevent beginners like me to bump into: AttributeError: 'dict' object has no attribute 'iteritems' and search elsewhere (e.g. Error “ 'dict' object has no attribute 'iteritems' ” when trying to use NetworkX's write_shp()) why this is happening.

    def myfunc(**kwargs):
    for k,v in kwargs.items():
       print("%s = %s" % (k, v))
    
    myfunc(abc=123, efh=456)
    # abc = 123
    # efh = 456
    

    and:

    def myfunc2(*args, **kwargs):
       for a in args:
           print(a)
       for k,v in kwargs.items():
           print("%s = %s" % (k, v))
    
    myfunc2(1, 2, 3, banan=123)
    # 1
    # 2
    # 3
    # banan = 123
    
    0 讨论(0)
  • 2020-11-22 00:56

    Adding to the other excellent posts.

    Sometimes you don't want to specify the number of arguments and want to use keys for them (the compiler will complain if one argument passed in a dictionary is not used in the method).

    def manyArgs1(args):
      print args.a, args.b #note args.c is not used here
    
    def manyArgs2(args):
      print args.c #note args.b and .c are not used here
    
    class Args: pass
    
    args = Args()
    args.a = 1
    args.b = 2
    args.c = 3
    
    manyArgs1(args) #outputs 1 2
    manyArgs2(args) #outputs 3
    

    Then you can do things like

    myfuns = [manyArgs1, manyArgs2]
    for fun in myfuns:
      fun(args)
    
    0 讨论(0)
提交回复
热议问题