Movatterモバイル変換


[0]ホーム

URL:


Following system colour schemeSelected dark colour schemeSelected light colour scheme

Python Enhancement Proposals

PEP 457 – Notation For Positional-Only Parameters

Author:
Larry Hastings <larry at hastings.org>
Discussions-To:
Python-Dev list
Status:
Final
Type:
Informational
Created:
08-Oct-2013

Table of Contents

Overview

This PEP proposes a notation for positional-only parameters in Python.Positional-only parameters are parameters without an externally-usablename; when a function accepting positional-only parameters is called,positional arguments are mapped to these parameters based solely ontheir position.

This PEP is an Informational PEP describing the notation for use whendescribing APIs that use positional-only parameters (e.g. in ArgumentClinic, or in the string representation ofinspect.Signatureobjects). A separate PEP,PEP 570, proposes elevation of this notationto full Python syntax.

Rationale

Python has always supported positional-only parameters.Early versions of Python lacked the concept of specifyingparameters by name, so naturally all parameters werepositional-only. This changed around Python 1.0, whenall parameters suddenly became positional-or-keyword.But, even in current versions of Python, many CPython“builtin” functions still only accept positional-onlyarguments.

Functions implemented in modern Python can acceptan arbitrary number of positional-only arguments, via thevariadic*args parameter. However, there is no Pythonsyntax to specify accepting a specific number ofpositional-only parameters. Put another way, there aremany builtin functions whose signatures are simply notexpressible with Python syntax.

This PEP proposes a notation for such signatures that could form thebasis of a backwards-compatible syntax that should permit implementingany builtin in pure Python code (seePEP 570 for that proposal).

Positional-Only Parameter Semantics In Current Python

There are many, many examples of builtins that onlyaccept positional-only parameters. The resultingsemantics are easily experienced by the Pythonprogrammer–just try calling one, specifying itsarguments by name:

>>>pow(x=5,y=3)Traceback (most recent call last):  File"<stdin>", line1, in<module>TypeError:pow() takes no keyword arguments

In addition, there are some functions with particularlyinteresting semantics:

  • range(), which accepts an optional parameterto theleft of its required parameter.[2]
  • dict(), whose mapping/iterator parameter is optional andsemantically must be positional-only. Any externallyvisible name for this parameter would occludethat name going into the**kwarg keyword variadicparameter dict![1]

Obviously one can simulate any of these in pure Python codeby accepting(*args,**kwargs) and parsing the argumentsby hand. But this results in a disconnect between thePython function’s signature and what it actually accepts,not to mention the work of implementing said argument parsing.

Motivation

This PEP does not propose we implement positional-onlyparameters in Python. The goal of this PEP is simplyto define the syntax, so that:

  • Documentation can clearly, unambiguously, andconsistently express exactly how the argumentsfor a function will be interpreted.
  • The syntax is reserved for future use, in casethe community decides someday to add positional-onlyparameters to the language.
  • Argument Clinic can use a variant of the syntaxas part of its input when definingthe arguments for built-in functions.

The Current State Of Documentation For Positional-Only Parameters

The documentation for positional-only parameters is incompleteand inconsistent:

  • Some functions denote optionalgroups of positional-only argumentsby enclosing them in nested square brackets.[3]
  • Some functions denote optional groups of positional-only argumentsby presenting multiple prototypes with varying numbers ofarguments.[4]
  • Some functions useboth of the above approaches.[2][5]

One more important idea to consider: currently in the documentationthere’s no way to tell whether a function takes positional-onlyparameters.open() accepts keyword arguments,ord() doesnot, but there is no way of telling just by reading thedocumentation that this is true.

Syntax And Semantics

From the “ten-thousand foot view”, and ignoring*args and**kwargsfor now, the grammar for a function definition currently looks like this:

defname(positional_or_keyword_parameters,*,keyword_only_parameters):

Building on that perspective, the new syntax for functions would looklike this:

defname(positional_only_parameters,/,positional_or_keyword_parameters,*,keyword_only_parameters):

All parameters before the/ are positional-only. If/ isnot specified in a function signature, that function does notaccept any positional-only parameters.

Positional-only parameters can have a default value, and if theydo they are optional. Positional-only parameters that don’t havea default value are “required” positional-only parameters.

More semantics of positional-only parameters:

  • Although positional-only parameter technically have names,these names are internal-only; positional-only parametersarenever externally addressable by name. (Similarlyto*args and**kwargs.)
  • If there are arguments after the/, then you must specifya comma after the/, just as there is a commaafter the* denoting the shift to keyword-only parameters.
  • This syntax has no effect on*args or**kwargs.

Additional Limitations

Argument Clinic uses a form of this syntax for specifyingbuiltins. It imposes further limitations that aretheoretically unnecessary but make the implementationeasier. Specifically:

  • A function that has positional-only parameters currentlycannot have any other kind of parameter. (This willprobably be relaxed slightly in the near future.)
  • Argument Clinic supports an additional syntax called“optional groups”. An “optional group” is a sequentialset of positional-only parameters that must be specifiedor not-specified as a group. If, for example, you definea function in Argument Clinic that takes four parameters,and all of them are positional-only and in one optionalgroup, then when calling the function you must specifyeither zero arguments or four arguments. This is necessaryto cover more of Python’s legacy library, but is outsidethe scope of this PEP, and is not recommended for actualinclusion in the Python language.

Notes For A Future Implementor

If we decide to implement positional-only parameters in a futureversion of Python, we’d have to do some additional work to preservetheir semantics. The problem: how do we inform a parameter thatno value was passed in for it when the function was called?

The obvious solution: add a new singleton constant to Pythonthat is passed in when a parameter is not mapped to an argument.I propose that the value be calledundefined,and be a singleton of a special class calledUndefined.If a positional-only parameter did not receive an argumentwhen called, its value would be set toundefined.

But this raises a further problem. How do can we tell thedifference between “this positional-only parameter did notreceive an argument” and “the caller passed inundefinedfor this parameter”?

It’d be nice to make it illegal to passundefined inas an argument to a function–to, say, raise an exception.But that would slow Python down, and the “consenting adults”rule appears applicable here. So making it illegal shouldprobably be strongly discouraged but not outright prevented.

However, it should be allowed (and encouraged) for userfunctions to specifyundefined as a default value forparameters.

Unresolved Questions

There are three types of parameters in Python:

  1. positional-only parameters,
  2. positional-or-keyword parameters, and
  3. keyword-only parameters.

Python allows functions to have both 2 and 3. And somebuiltins (e.g. range) have both 1 and 3. Does it makesense to have functions that have both 1 and 2? Orall of the above?

Thanks

Credit for the use of ‘/’ as the separator between positional-only and positional-or-keywordparameters goes to Guido van Rossum, in a proposal from 2012.[6]

Credit for making left option groups higher precedence goes toAlyssa Coghlan. (Conversation in person at PyCon US 2013.)

[1]
http://docs.python.org/3/library/stdtypes.html#dict
[2] (1,2)
http://docs.python.org/3/library/functions.html#func-range
[3]
http://docs.python.org/3/library/curses.html#curses.window.border
[4]
http://docs.python.org/3/library/os.html#os.sendfile
[5]
http://docs.python.org/3/library/curses.html#curses.window.addch
[6]
Guido van Rossum, posting to python-ideas, March 2012:https://mail.python.org/pipermail/python-ideas/2012-March/014364.htmlandhttps://mail.python.org/pipermail/python-ideas/2012-March/014378.htmlandhttps://mail.python.org/pipermail/python-ideas/2012-March/014417.html

Copyright

This document has been placed in the public domain.


Source:https://github.com/python/peps/blob/main/peps/pep-0457.rst

Last modified:2025-02-01 08:59:27 GMT


[8]ページ先頭

©2009-2025 Movatter.jp