This PEP proposes to extend Python’s syntax and number-from-stringconstructors so that underscores can be used as visual separators fordigit grouping purposes in integral, floating-point and complex numberliterals.
This is a common feature of other modern languages, and can aidreadability of long literals, or literals whose value should clearlyseparate into parts, such as bytes or words in hexadecimal notation.
Examples:
# grouping decimal numbers by thousandsamount=10_000_000.0# grouping hexadecimal addresses by wordsaddr=0xCAFE_F00D# grouping bits into nibbles in a binary literalflags=0b_0011_1111_0100_1110# same, for string conversionsflags=int('0b_1111_0000',2)
The current proposal is to allow one underscore between digits, andafter base specifiers in numeric literals. The underscores have nosemantic meaning, and literals are parsed as if the underscores wereabsent.
The production list for integer literals would therefore look likethis:
integer:decinteger|bininteger|octinteger|hexintegerdecinteger:nonzerodigit(["_"]digit)*|"0"(["_"]"0")*bininteger:"0"("b"|"B")(["_"]bindigit)+octinteger:"0"("o"|"O")(["_"]octdigit)+hexinteger:"0"("x"|"X")(["_"]hexdigit)+nonzerodigit:"1"..."9"digit:"0"..."9"bindigit:"0"|"1"octdigit:"0"..."7"hexdigit:digit|"a"..."f"|"A"..."F"
For floating-point and complex literals:
floatnumber:pointfloat|exponentfloatpointfloat:[digitpart]fraction|digitpart"."exponentfloat:(digitpart|pointfloat)exponentdigitpart:digit(["_"]digit)*fraction:"."digitpartexponent:("e"|"E")["+"|"-"]digitpartimagnumber:(floatnumber|digitpart)("j"|"J")
Following the same rules for placement, underscores will be allowed inthe following constructors:
int() (with any base)float()complex()Decimal()The new-style number-to-string formatting language will be extended toallow_ as a thousands separator, where currently only, issupported. This can be used to easily generate code with morereadable literals.[11]
The syntax would be the same as for the comma, e.g.{:10_} for awidth of 10 with_ separator.
For theb,x ando format specifiers,_ will beallowed and group by 4 digits.
Those languages that do allow underscore grouping implement a largevariety of rules for allowed placement of underscores. In cases wherethe language spec contradicts the actual behavior, the actual behavioris listed. (“single” or “multiple” refer to allowing runs ofconsecutive underscores.)
Instead of the relatively strict rule specified above, the use ofunderscores could be less limited. As seen in other languages, commonrules include:
The syntax in this PEP has ultimately been selected because it coversthe common use cases, and does not allow for syntax that would have tobe discouraged in style guides anyway.
A less common rule would be to allow underscores only every N digits(where N could be 3 for decimal literals, or 4 for hexadecimal ones).This is unnecessarily restrictive, especially considering theseparator placement is different in different cultures.
A proposed alternate syntax was to use whitespace for grouping.Although strings are a precedent for combining adjoining literals, thebehavior can lead to unexpected effects which are not possible withunderscores. Also, no other language is known to use this rule,except for languages that generally disregard any whitespace.
C++14 introduces apostrophes for grouping (because underscoresintroduce ambiguity with user-defined literals), which is notconsidered because of the use in Python’s string literals.[1]
A preliminary patch that implements the specification given above hasbeen posted to the issue tracker.[12]
This document has been placed in the public domain.
Source:https://github.com/python/peps/blob/main/peps/pep-0515.rst
Last modified:2025-02-01 08:59:27 GMT