views:

255

answers:

1

In cPython 2.4:

def f(a,b,c,d):
    pass

>>> f(b=1,c=1,d=1)
TypeError: f() takes exactly 4 non-keyword arguments (0 given)

but:

>>> f(a=1,b=1,c=1)
TypeError: f() takes exactly 4 non-keyword arguments (3 given)

Clearly, I don't really really understand Python's function-argument processing mechanism. Anyone care to share some light on this? I see what's happening (something like filling argument slots, then giving up), but I think this would foul up a newbie.

(also, if people have better question keywords -- something like "guts" -- please retag)

+9  A: 

When you say

def f(a,b,c,d):

you are telling python that f takes 4 positional arguments. Every time you call f it must be given exactly 4 arguments, and the first value will be assigned to a, the second to b, etc.

You are allowed to call f with something like

f(1,2,3,4) or f(a=1,b=2,c=3,d=4), or even f(c=3,b=2,a=1,d=4)

but in all cases, exactly 4 arguments must be supplied.

f(b=1,c=1,d=1) returns an error because no value has been supplied for a. (0 given) f(a=1,b=1,c=1) returns an error because no value has been supplied for d. (3 given)

The number of args given indicates how far python got before realizing there is an error.

By the way, if you say

def f(a=1,b=2,c=3,d=4):

then your are telling python that f takes 4 optional arguments. If a certain arg is not given, then its default value is automatically supplied for you. Then you could get away with calling

f(a=1,b=1,c=1) or f(b=1,c=1,d=1)

unutbu
So, this is exactly the non-obvious part: **The number of args given indicates how far python got before realizing there is an error.** I'd file this under "wart that can bite novices", since in fact, 3 are given in both cases.
Gregg Lind
At least you got an error ;)
telliott99