f-string是带有 'f'
或 'F'
前缀的字符串字面值。这种字符串可包含替换字段,即以 {}
标示的表达式。而其他字符串字面值总是一个常量,格式化字符串字面值实际上是会在运行时被求值的表达式。
转义序列会像在普通字符串字面值中一样被解码 (除非字面值还被标示为原始字符串)。解码之后,字符串内容所用的语法如下:
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 ::=
字符串在花括号以外的部分按其字面值处理,除了双重花括号 '{{'
或 '}}'
会被替换为相应的单个花括号。单个左花括号 '{'
标示一个替换字段,它以一个 Python 表达式打头,表达式之后可能有一个以叹号 '!'
标示的转换字段。之后还可能带有一个以冒号 ':'
标示的格式说明符。替换字段以一个右花括号 '}'
作为结束。
格式化字符串字面值中的表达式会被当作正常的包含在圆括号中的 Python 表达式一样处理,但有少数例外。空表达式不被允许,lambda
表达式必须显式地加上圆括号。替换表达式可以包含换行 (例如在三引号字符串中),但是不能包含注释。每个表达式会在格式化字符串字面值所包含的位置按照从左至右的顺序被求值。
在 3.7 版更改: 在 Python 3.7 之前, await
表达式包含 async for
子句的推导式不允许在格式化字符串字面值表达式中使用,这是因为具体实现存在一个问题。
如果指定了转换符,表达式的求值结果会先转换再格式化。转换符 '!s'
即对结果调用 str()
,'!r'
为调用 repr()
,而 '!a'
为调用 ascii()
。
name = 'Jack'
print(f"str: {name}")
num = 6
print(f"int: {num}")
price = 3.33
print(f"float: {price}")
print(f"{2 * 3}")
print(f"{name.upper()}")
import math
print(f"{math.pi}")
print(f"{(lambda x, y: x+y*2)(3, 2)}")
lambda表达式必须显式地加上圆括号, 第二个小括号表示传入的参数
slogan = 'Python NB'
print(f"{slogan:>20}")
# ' Python NB'
print(f"{slogan:<20}")
# 'Python NB '
print(f"{slogan:^20}")
# ' Python NB '
# 使用指定字符填充
print(f"{slogan:-^20}")
# '-----Python NB------'
a = 1
b = -9
print(f"{a:+}", f"{b:+}")
# ('+1', '-9')
print(f"{a:-}", f"{b:-}")
('1', '-9')
print(f"{a: }", f"{b: }")
(' 1', '-9')
格式描述符 | 含义 |
---|---|
width | 整数width指定宽度 |
0width | 整数width指定宽度, 0表示最高位用0补足宽度 |
width.precision | 整数width指定宽度, 整数precision表示显示精度 |
a = 123.456
# width
print(f'{a:10}')
# ' 123.456'
# 0width
print(f'{a:010}')
# '000123.456'
# width.precision
print(f"{a:8.2f}")
# ' 123.46'
from datetime import *
d = date.today()
print(d)
# datetime.date(2020, 5, 13)
print(f"{d:%Y-%m-%d}")
# '2020-05-13'