The definition of a function is the following:
def testf(t,t1 = 0,*x):
... print t
... print t1
... print x[0]
... return sin(x[0]*t*t1)
...
I call function as testf(pi,t1=1,1). The error I receive is
SyntaxError: non-keyword arg after keyword arg
Is there anything wrong with function call?
I received the same error if I call the function testf(t1=1,t=pi,1)
I will not receive error message if I call the function testf(pi,1,1).
I have another question about calling this function.
It is possible to call the function with default value of t1 and x, which is not None, as a tuple?
Thanks a lot for your help.
3 Answers 3
In your function,
tis a positional argumentt1is a keyword argument, with a default value (also a positional argument at position 1)xis a collection of all the other positional arguments
As the error message says, any Python function should have all the positional variables before any keyword arguments. You have to invoke the function like this
testf(math.pi, t1=1)
When you pass a keyword argument, that should be the last argument to the function (or only keyword arguments can follow that).
When you say
testf(math.pi, 1, t1 = 2)
Both 1 and 2 are to be assigned to t1 (t1 is also a positional variable at index 1), which is not possible. So, error will be thrown in this case also.
def testf(t, t1 = 0, *x):
print t, x, t1
testf(5)
# 5 () 0 -> `t` is 5, `t1` takes the default value, `x` is empty
testf(5, 10, 15, 20)
# 5 (15, 20) 10 -> `t` is 5, `t1` is 10, `x` is 15 and 20
testf(5, t1 = 20)
# 5 () 20 -> `t` is 5, `t1` is 20, `x` is empty
testf(5, 10, t1 = 20)
# TypeError: testf() got multiple values for keyword argument 't1'
testf(5, t1 = 20, 10)
# SyntaxError: non-keyword arg after keyword arg
8 Comments
t1.Positional arguments must correspond to the first n parameters of a function, where n is the number of positional arguments provided. You can't mix a keyword argument in with them; keyword arguments must go after all positional arguments.
In theory, the language could have been designed otherwise, but it would be confusing what the positional arguments would mean under such circumstances, and there is no benefit to motivate the added complexity. For example, it's unclear whether in
def f(a=1, b=1, c=1): pass
f(c=1, 2)
the 2 is supposed to provide the value of a or b.
If you want to call your function, provide t1 positionally:
testf(pi, 1, 1)
Note that the presence or absence of a default value for a parameter, such as t1, has no effect on whether you can provide it as a keyword argument or positional argument.
Comments
You should provide non-keyword arguments before a keyword argument
testf(pi,1,t1=1)
some example with args and keyword args:
def testf(t,*x,**keywords):
t1=keywords['t1'] if 't1' in keywords else 0
print t,x,keywords,t1
testf(1,5,t1=1)
testf(1,2,3,4)
testf(1,5)
testf(1)
will output
1 (5,) {'t1': 1} 1 <---- t1 = 1
1 (2, 3, 4) {} 0 <---- t1 = 0
1 (5,) {} 0
1 () {} 0