bpo-36540: Documentation for PEP570 - Python positional only argument… · python/cpython@b76302d
@@ -519,6 +519,176 @@ and of course it would print:
519519Note that the order in which the keyword arguments are printed is guaranteed
520520to match the order in which they were provided in the function call.
521521522+Special parameters
523+------------------
524+525+By default, arguments may be passed to a Python function either by position
526+or explicitly by keyword. For readability and performance, it makes sense to
527+restrict the way arguments can be passed so that a developer need only look
528+at the function definition to determine if items are passed by position, by
529+position or keyword, or by keyword.
530+531+A function definition may look like:
532+533+.. code-block:: none
534+535+ def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
536+ ----------- ---------- ----------
537+ | | |
538+ | Positional or keyword |
539+ | - Keyword only
540+ -- Positional only
541+542+where ``/`` and ``*`` are optional. If used, these symbols indicate the kind of
543+parameter by how the arguments may be passed to the function:
544+positional-only, positional-or-keyword, and keyword-only. Keyword parameters
545+are also referred to as named parameters.
546+547+-------------------------------
548+Positional-or-Keyword Arguments
549+-------------------------------
550+551+If ``/`` and ``*`` are not present in the function definition, arguments may
552+be passed to a function by position or by keyword.
553+554+--------------------------
555+Positional-Only Parameters
556+--------------------------
557+558+Looking at this in a bit more detail, it is possible to mark certain parameters
559+as *positional-only*. If *positional-only*, the parameters' order matters, and
560+the parameters cannot be passed by keyword. Positional-only parameters are
561+placed before a ``/`` (forward-slash). The ``/`` is used to logically
562+separate the positional-only parameters from the rest of the parameters.
563+If there is no ``/`` in the function definition, there are no positional-only
564+parameters.
565+566+Parameters following the ``/`` may be *positional-or-keyword* or *keyword-only*.
567+568+----------------------
569+Keyword-Only Arguments
570+----------------------
571+572+To mark parameters as *keyword-only*, indicating the parameters must be passed
573+by keyword argument, place an ``*`` in the arguments list just before the first
574+*keyword-only* parameter.
575+576+-----------------
577+Function Examples
578+-----------------
579+580+Consider the following example function definitions paying close attention to the
581+markers ``/`` and ``*``::
582+583+ >>> def standard_arg(arg):
584+ ... print(arg)
585+ ...
586+ >>> def pos_only_arg(arg, /):
587+ ... print(arg)
588+ ...
589+ >>> def kwd_only_arg(*, arg):
590+ ... print(arg)
591+ ...
592+ >>> def combined_example(pos_only, /, standard, *, kwd_only):
593+ ... print(pos_only, standard, kwd_only)
594+595+596+The first function definition, ``standard_arg``, the most familiar form,
597+places no restrictions on the calling convention and arguments may be
598+passed by position or keyword::
599+600+ >>> standard_arg(2)
601+ 2
602+603+ >>> standard_arg(arg=2)
604+ 2
605+606+The second function ``pos_only_arg`` is restricted to only use positional
607+parameters as there is a ``/`` in the function definition::
608+609+ >>> pos_only_arg(1)
610+ 1
611+612+ >>> pos_only_arg(arg=1)
613+ Traceback (most recent call last):
614+ File "<stdin>", line 1, in <module>
615+ TypeError: pos_only_arg() got an unexpected keyword argument 'arg'
616+617+The third function ``kwd_only_args`` only allows keyword arguments as indicated
618+by a ``*`` in the function definition::
619+620+ >>> kwd_only_arg(3)
621+ Traceback (most recent call last):
622+ File "<stdin>", line 1, in <module>
623+ TypeError: kwd_only_arg() takes 0 positional arguments but 1 was given
624+625+ >>> kwd_only_arg(arg=3)
626+ 3
627+628+And the last uses all three calling conventions in the same function
629+definition::
630+631+ >>> combined_example(1, 2, 3)
632+ Traceback (most recent call last):
633+ File "<stdin>", line 1, in <module>
634+ TypeError: combined_example() takes 2 positional arguments but 3 were given
635+636+ >>> combined_example(1, 2, kwd_only=3)
637+ 1 2 3
638+639+ >>> combined_example(1, standard=2, kwd_only=3)
640+ 1 2 3
641+642+ >>> combined_example(pos_only=1, standard=2, kwd_only=3)
643+ Traceback (most recent call last):
644+ File "<stdin>", line 1, in <module>
645+ TypeError: combined_example() got an unexpected keyword argument 'pos_only'
646+647+648+Finally, consider this function definition which has a potential collision between the positional argument ``name`` and ``**kwds`` which has ``name`` as a key::
649+650+ def foo(name, **kwds):
651+ return 'name' in kwds
652+653+There is no possible call that will make it return ``True`` as the keyword ``'name'``
654+will always to bind to the first parameter. For example::
655+656+ >>> foo(1, **{'name': 2})
657+ Traceback (most recent call last):
658+ File "<stdin>", line 1, in <module>
659+ TypeError: foo() got multiple values for argument 'name'
660+ >>>
661+662+But using ``/`` (positional only arguments), it is possible since it allows ``name`` as a positional argument and ``'name'`` as a key in the keyword arguments::
663+664+ def foo(name, /, **kwds):
665+ return 'name' in kwds
666+ >>> foo(1, **{'name': 2})
667+ True
668+669+In other words, the names of positional-only parameters can be used in
670+``**kwds`` without ambiguity.
671+672+-----
673+Recap
674+-----
675+676+The use case will determine which parameters to use in the function definition::
677+678+ def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
679+680+As guidance:
681+682+* Use positional-only if you want the name of the parameters to not be
683+ available to the user. This is useful when parameter names have no real
684+ meaning, if you want to enforce the order of the arguments when the function
685+ is called or if you need to take some positional parameters and arbitrary
686+ keywords.
687+* Use keyword-only when names have meaning and the function definition is
688+ more understandable by being explicit with names or you want to prevent
689+ users relying on the position of the argument being passed.
690+* For an API, use positional-only to prevent prevent breaking API changes
691+ if the parameter's name is modified in the future.
522692523693.. _tut-arbitraryargs:
524694