How are fstrings implemented in Python? I'm looking at the types via my IDE for strings and fstring variables have the same inferred type, str
. Is it a whole new class or implementing the same interface as string? An explanation of how it works would be great.
The reason I ask is because I want to evaluate if it would be reasonable for us to implement our version. Additionally, would it be possible to do it in such a way that IDEs would be able to infer different types based on the letter.
They're implemented (in CPython anyway) somewhere over...
I may have missed some spots.
Based on this, I'd say adding other prefixes will be tough and you'd essentially be creating your own fork of Python.
From PEP 498:
F-strings provide a way to embed expressions inside string literals, using a minimal syntax. It should be noted that an f-string is really an expression evaluated at run time, not a constant value. In Python source code, an f-string is a literal string, prefixed with 'f', which contains expressions inside braces. The expressions are replaced with their values.
fstrings are implemented inside CPython - Processing them is essentially evaluating the expression enclosed within the curly braces, here's one example from CPython source code where the expressions are being parsed.
We can use dis
to observe the opcodes:
import dis
dis.dis("f'{x}'")
1 0 LOAD_NAME 0 (x)
2 FORMAT_VALUE 0
4 RETURN_VALUE
dis.dis("x")
0 LOAD_NAME 0 (x)
2 RETURN_VALUE
You can see that the only added opcode is FORMAT_VALUE
, which confirms that there's no added overhead to fstrings and they are actually an expression, as opposed to format
for example, where we see LOAD_CONST
, LOAD_ATTR
and CALL_FUNCTION
:
In [9]: dis.dis('"{}".format(x)')
1 0 LOAD_CONST 0 ('{}')
2 LOAD_ATTR 0 (format)
4 LOAD_NAME 1 (x)
6 CALL_FUNCTION 1
8 RETURN_VALUE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With