The Python Language Reference, Release 3.9.5 2.4.2 String literal concatenation 2.4.3 Formatted string literals Chapter 2. Lexical analysis 12 If a conversion is specified, the result of evaluating the expression is converted before formatting. Conversion$_{'!s'}$ New in version 3.8: The equal sign$_{'='}$ . When the equal sign$_{'='}$ is provided, the output will have the expression text, the$_{'='}$ and the evaluated value. Spaces after the opening brace$_{'{'}$ , within the expression and after the$_{'='}$ are all retained in the output. By default, the$_{'='}$ causes the$_{repr()}$ of the expression to be provided, unless there is a format specified. When a format is specified it defaults to the$_{str()}$ of the expression unless a conversion$_{'!r'}$ is declared. Changed in version 3.7: Prior to Python 3.7, an$_{await}$expression and comprehensions containing an$_{async for}$ clause were illegal in the expressions in formatted string literals due to a problem with the implementation. Expressions in formatted string literals are treated like regular Python expressions surrounded by parentheses, with a few exceptions. An empty expression is not allowed, and both$_{lambda}$and assignment expressions$_{:=}$ must be surrounded by explicit parentheses. Replacement expressions can contain line breaks (e.g. in triple-quoted strings), but they cannot contain comments. Each expression is evaluated in the context where the formatted string literal appears, in order from left to right. The parts of the string outside curly braces are treated literally, except that any doubled curly braces$_{'{{'}$or$_{'}}'}$ are replaced with the corresponding single curly brace. A single opening curly bracket$_{'{'}$ marks a replacement field, which starts with a Python expression. To display both the expression text and its value after evaluation, (useful in debugging), an equal sign$_{'='}$ may be added after the expression. A conversion field, introduced by an exclamation point$_{'!'}$ may follow. A format specifier may also be appended, introduced by a colon$_{':'}$ . A replacement field ends with a closing curly bracket$_{'}'}$ . f_string ::= ( literal_char | "{{" | "}}" | replacement_field )* $_{replacement_field}$::= "{" f_expression ["="] ["!" conversion ] [":" format_spec ] "}" f_expression ::= ( conditional_expression | "*" or_expr ) ("," conditional_expression | "," "*" or_expr )* [","] | yield_expression conversion ::= "s" | "r" | "a" format_spec ::= ( literal_char | NULL | replacement_field )* literal_char ::= <any code point except "{", "}" or NULL> A formatted string literal or f-string is a string literal that is prefixed with 'f' or 'F' . These strings may contain replacement fields, which are expressions delimited by curly braces$_{{}}$ . While other string literals always have a constant value, formatted strings are really expressions evaluated at run time. Escape sequences are decoded like in ordinary string literals (except when a literal is also marked as a raw string). After decoding, the grammar for the contents of the string is: New in version 3.6. Note that this feature is defined at the syntactical level, but implemented at compile time. The ‘+’ operator must be used to concatenate string expressions at run time. Also note that literal concatenation can use different quoting styles for each component (even mixing raw strings and triple quoted strings), and formatted string literals may be concatenated with plain string literals. Multiple adjacent string or bytes literals (delimited by whitespace), possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation. Thus,$_{"hello" 'world'}$ is equivalent to "helloworld" . This feature can be used to reduce the number of backslashes needed, to split long strings con- veniently across long lines, or even to add comments to parts of strings, for example: re.compile("[A-Za-z_]" # letter or underscore "[A-Za-z0-9_]* " # letter, digit or underscore )