merge
This commit is contained in:
commit
eb8155bac5
91
pep-0498.txt
91
pep-0498.txt
|
@ -208,6 +208,25 @@ Expressions cannot contain ':' or '!' outside of strings or parens,
|
|||
brackets, or braces. The exception is that the '!=' operator is
|
||||
special cased.
|
||||
|
||||
Escape sequences
|
||||
----------------
|
||||
|
||||
Scanning an f-string for expressions happens after escape sequences
|
||||
are decoded. Because hex(ord('{')) == 0x7b, the f-string
|
||||
f'\\u007b4*10}' is decoded to f'{4*10}', which evaluates as the integer
|
||||
40::
|
||||
|
||||
>>> f'\u007b4*10}'
|
||||
'40'
|
||||
>>> f'\x7b4*10}'
|
||||
'40'
|
||||
>>> f'\x7b4*10\N{RIGHT CURLY BRACKET}'
|
||||
'40'
|
||||
|
||||
These examples aren't generally useful, they're just to show that
|
||||
escape sequences are processed before f-strings are parsed for
|
||||
expressions.
|
||||
|
||||
Code equivalence
|
||||
----------------
|
||||
|
||||
|
@ -360,6 +379,25 @@ Leading and trailing whitespace in expressions is skipped
|
|||
For ease of readability, leading and trailing whitespace in
|
||||
expressions is ignored.
|
||||
|
||||
Evaluation order of expressions
|
||||
-------------------------------
|
||||
|
||||
The expressions in an f-string are evaluated in left-to-right
|
||||
order. This is detectable only if the expressions have side effects::
|
||||
|
||||
>>> def fn(l, incr):
|
||||
... result = l[0]
|
||||
... l[0] += incr
|
||||
... return result
|
||||
...
|
||||
>>> lst = [0]
|
||||
>>> f'{fn(lst,2)} {fn(lst,3)}'
|
||||
'0 2'
|
||||
>>> f'{fn(lst,2)} {fn(lst,3)}'
|
||||
'5 7'
|
||||
>>> lst
|
||||
[10]
|
||||
|
||||
Discussion
|
||||
==========
|
||||
|
||||
|
@ -403,7 +441,7 @@ used. A quick search of Python's standard library shows only a handful
|
|||
of uses of string.Template, but hundreds of uses of str.format().
|
||||
|
||||
Another proposed alternative was to have the substituted text between
|
||||
\{ and } or between \{ and \}. While this syntax would probably be
|
||||
\\{ and } or between \\{ and \\}. While this syntax would probably be
|
||||
desirable if all string literals were to support interpolation, this
|
||||
PEP only supports strings that are already marked with the leading
|
||||
'f'. As such, the PEP is using unadorned braces to denoted substituted
|
||||
|
@ -473,6 +511,15 @@ use variables as index values::
|
|||
See [#]_ for a further discussion. It was this observation that led to
|
||||
full Python expressions being supported in f-strings.
|
||||
|
||||
Furthermore, the limited expressions that str.format() understands
|
||||
need not be valid Python expressions. For example::
|
||||
|
||||
>>> '{i[";]}'.format(i={'";':4})
|
||||
'4'
|
||||
|
||||
For this reason, the str.format() "expression parser" is not suitable
|
||||
for use when implementing f-strings.
|
||||
|
||||
Triple-quoted f-strings
|
||||
-----------------------
|
||||
|
||||
|
@ -593,15 +640,45 @@ having 2 expressions::
|
|||
|
||||
f'{x:.{width}}'
|
||||
|
||||
Expressions with side effects
|
||||
-----------------------------
|
||||
The same expression used multiple times
|
||||
---------------------------------------
|
||||
|
||||
xxx
|
||||
Every expression in braces in an f-string is evaluated exactly
|
||||
once. If the same expression is used more than once in the same
|
||||
f-string, it will be evaluated multiple times. However, it's undefined
|
||||
which result will show up in the resulting string value. For purposes
|
||||
of this section, two expressions are the same if they have the exact
|
||||
same literal text defining them. For example, '{i}' and '{i}' are the
|
||||
same expression, but '{i}' and '{ i}' are not, due to the extra space
|
||||
in the second expression.
|
||||
|
||||
Expressions used multiple times
|
||||
-------------------------------
|
||||
For example, given::
|
||||
|
||||
xxx
|
||||
>>> def fn(lst):
|
||||
... lst[0] += 1
|
||||
... return lst[0]
|
||||
...
|
||||
>>> lst=[0]
|
||||
>>> f'{fn(lst)} {fn(lst)}'
|
||||
'1 2'
|
||||
|
||||
The resulting f-string might have the value '1 2', '2 2', '1 1', or
|
||||
even '2 1'.
|
||||
|
||||
However::
|
||||
|
||||
>>> lst=[0]
|
||||
>>> f'{fn(lst)} { fn(lst)}'
|
||||
'1 2'
|
||||
|
||||
This f-string will always have the value '1 2'. This is due to the two
|
||||
expressions not being the same: the space in the second example makes
|
||||
the two expressions distinct.
|
||||
|
||||
This restriction is in place in order to allow for a possible future
|
||||
extension allowing translated strings, wherein the expression
|
||||
substitutions would be identified by their text values as they show up
|
||||
between the braces.
|
||||
|
||||
References
|
||||
==========
|
||||
|
|
|
@ -166,7 +166,7 @@ following semantics::
|
|||
__slots__ = ("raw_template", "parsed_fields", "field_values")
|
||||
|
||||
def __new__(cls, raw_template, parsed_fields, field_values):
|
||||
self = super().__new__()
|
||||
self = super().__new__(cls)
|
||||
self.raw_template = raw_template
|
||||
self.parsed_fields = parsed_fields
|
||||
self.field_values = field_values
|
||||
|
|
Loading…
Reference in New Issue