Using default arguments before positional arguments

后端 未结 3 2219
长情又很酷
长情又很酷 2021-02-13 15:18

I am learning to use positional arguments in python and also trying to see how they work when mixed up with default arguments:-

def withPositionalArgs(ae=9,*args         


        
相关标签:
3条回答
  • 2021-02-13 15:28

    In Python2, you are not allowed to put arguments which have a default value before positional arguments.

    The positional arguments must come first, then the arguments with default values (or, when calling the function, the keyword arguments), then *args, and then **kwargs.

    This order is required for both the function definition and for function calls.

    In Python3, the order has been relaxed. (For example, *args can come before a keyword argument in the function definition.) See PEP3102.

    0 讨论(0)
  • 2021-02-13 15:38

    Python3 has relaxed ordering.

    Now you can do something like:

    def withPositionalArgs(*args, ae=9):
        print('ae=', ae)
        print('args =', args)
    a=1
    b=2
    c=[10, 20]
    withPositionalArgs(a, b, c, ae=7)
    
    0 讨论(0)
  • 2021-02-13 15:52

    I think we should make the distinction of default values vs. passing in arbitrary arguments/key-value pairs. The behaviour without default values is the same:

    def f(ae,*args, **kwargs):
        print 'ae     = ', ae
        print 'args   = ', args
        print 'kwargs = ', kwargs
    

    The way we have written this means that the first argument passed into f in the tuple args, that is f(1,2,3,a=1,b=2) (the sequence goes explicit arguments, *args, **kwargs.) Here: ae = 1, args = (2,3), kwargs = {'a': 1, 'b': 2}.

    If we try to pass in f(1,2,3,a=1,ae=3) we are thrown a TypeError: f() got multiple values for keyword argument 'ae', since the value of ae is attempted to be changed twice.

    .

    One way around this is to only set ae when it is explicitly prescribed, we could (after the def line):

    def g(*args, **kwargs):
        kwargs, kwargs_temp = {"ae": 9}, kwargs
        kwargs.update(kwargs_temp) #merge kwargs into default dictionary
    

    and this time g(1,2,3,a=1,ae=3) sets args=(1,2,3), kwargs={a=1,ae=3}.

    However, I suspect this is not best practice...

    0 讨论(0)
提交回复
热议问题