I am trying to make my code NOT to accept keyword arguments just like some bulitins also do not accept keyword arguments, but, I am unable to do so. Here, is my thinking according to my limited understanding:-
def somefunc(a,b):
print a,b
somefunc(10,20)
Output:
10 20
Now, When I run the following (I know this is not expected to be keyword argument in the function definition, but, looking at the function call, it seems to be the same syntax as that of when calling a function which accepts keyword arguments):
somefunc(b=10,a=20)
Output:
20 10
I have 2 questions:-
somefunc(b=10,a=20)
and not the function definition, this can seem to be either of a call to a function which accepts just normal arguments or a function which accepts keyword arguments. How does the interpreter differentiate between the two?Why I want to do this at all? I am just checking if I can do this, so that I do not miss anything in understanding python in depth. I do knot know whether python allows that or not.
ad 1) Correct names are verified automatically by Python if they are called like somefunct(name=value, ...)
. I don't need to remember the exact standard order of parameters and to verify it too "neurotic" by looking into the documentation every month at every usage, if I remember a function with nice descriptive names of parameters. A call with named parameters can be easily verified by a test or by use. On the contrary, the correct order of used parameters can be verified only by reading the documentation. Calling by named parameters is preferred over a very long list of positional parameters. Therefore the reported behavior is well-founded. (Short single letter parameters "a, b" don't help against mistakes of course.)
ad 2) Positional-only parameters defined in Python code are possible in Python 3.8 and newer by a new function parameter syntax /
to indicate that some function parameters must be specified positional and cannot be used as keyword arguments.
def somefunc(a, b, /):
print(a, b)
Originally it was possible only in C. Some well known builtin fast functions written in C with small fixed number of required parameters typically do not support calling with named parameters. (e.g. hasattr
)
This is because they use only a fast simple header ...(... PyObject *args)
and therefore all named parameters are rejected automatically. (Python can never introspect into names of arguments in C source. :-)
Many other C functions have a header ...(... PyObject *args, PyObject *kwds)
and they support exact list of names explicit by implementing much more complicated validation PyArg_ParseTupleAndKeywords
. These names must be written to docs strings manually.