user131983
user131983

Reputation: 3927

Order of Keyword and Non-Keyword Arguments

I have the following code:

def say_hello_then_call_f(f, *args, **kwargs):
    print 'args is', args
    print 'kwargs is', kwargs
    print("Hello! Now I'm going to call %s" % f)
    return f(*args, **kwargs)     # when calling a function, however, * unpacks a tuple and ** unpacks a dict

def g(x, y,s, z=1):
    return (x + y) / z

I don't understand why the line below results in an error "non-keyword arg after keyword arg". Does it have to be that a functions has Keywords Arguments and only then Non-Keyword Arguments, even when passing values?:

say_hello_then_call_f(g, 1, y=2,4, z=5.)

Thanks

Upvotes: 2

Views: 4372

Answers (2)

Slater Victoroff
Slater Victoroff

Reputation: 21914

icktoofay is correct, but I think it might be useful to go into a little more depth on this one. The reason for this is if you allow of keyword arguments, and then positional arguments, it inherently becomes ambiguous as to which position that argument should actually go into. Should it count the keyword arguments or not?

In your example:

say_hello_then_call_f(g, 1, y=2, 4, z=5.)

There are cases to be made both for 4 being the 4th, and the 3rd positional argument. If you count keyword arguments as positional arguments, there's no reason to specify the word associated with the argument, and if you don't, then you have a non-constant interface to the function effectively.

Also, hard to say whether it goes in *args or **kwargs at that point.

Compounding on top of this, if we had argument ambiguity combined with python's duck-typing system, it would quickly lead to some problems that would be horrible to debug.

Upvotes: 2

icktoofay
icktoofay

Reputation: 129001

Yes, Python enforces an order on arguments: all non-keyword arguments must go first, followed by any keyword arguments.

Upvotes: 2

Related Questions