与标准 C 不同,所有无法识别的转义序列将原样保留在字符串中,也就是说,反斜杠会在结果中保留。(这种方式在调试时很有用: 如果输错了一个转义序列,更容易在输出结果中识别错误。) 另外要注意的一个关键点是:专用于字符串字面值中的转义序列如果在字节串字面值中出现,会被归类为无法识别的转义序列。
在 3.6 版更改: 无法识别的转义序列将引发 r"\"" 是一个有效的字符串字面值,包含两个字符: 一个反斜杠和一个双引号;而 r"\" 不是一个有效的字符串字面值 (即便是原始字符串也不能以奇数个反斜杠结束)。特别地,一个原始字面值不能以单个反斜杠结束 (因为此反斜杠会转义其后的引号字符)。还要注意一个反斜杠加一个换行在字面值中会被解释为两个字符,而 不是 一个连续行。
2.4.2. 字符串字面值拼接
多个相邻的字符串或字节串字面值 (以空白符分隔),所用的引号可以彼此不同,其含义等同于全部拼接为一体。因此, "hello" 'world' 等同于 "helloworld"。此特性可以减少反斜杠的使用,以方便地将很长的字符串分成多个物理行,甚至每部分字符串还可分别加注释,例如:
re.compile("[A-Za-z_]" # letter or underscore "[A-Za-z0-9_]*" # letter, digit or underscore )
注意此特性是在句法层面定义的,但是在编译时实现。在运行时拼接字符串表达式必须使用 '+' 运算符。还要注意字面值拼接时每个部分可以使用不同的引号风格 (甚至混合使用原始字符串和三引号字符串),格式化字符串字面值也可与普通字符串字面值拼接。
2.4.3. 格式化字符串字面值
3.6 新版功能.
格式化字符串字面值 或称 f-string 是带有 'f' 或 'F' 前缀的字符串字面值。这种字符串可包含替换字段,即以 {} 标示的表达式。而其他字符串字面值总是一个常量,格式化字符串字面值实际上是会在运行时被求值的表达式。
转义序列会像在普通字符串字面值中一样被解码 (除非字面值还被标示为原始字符串)。解码之后,字符串内容所用的语法如下:
f_string ::= (replacement_field ::= "{" f_expression ::= (conversion ::= "s" | "r" | "a" format_spec ::= (literal_char ::=
字符串在花括号以外的部分按其字面值处理,除了双重花括号 '{{' 或 '}}' 会被替换为相应的单个花括号。单个左花括号 '{' 标示一个替换字段,它以一个 Python 表达式打头,表达式之后可能有一个以叹号 '!' 标示的转换字段。之后还可能带有一个以冒号 ':' 标示的格式说明符。替换字段以一个右花括号 '}' 作为结束。
格式化字符串字面值中的表达式会被当作包含在圆括号中的普通 Python 表达式一样处理,但有少数例外。 空表达式不被允许,:= 必须显式地加上圆括号。 替换表达式可以包含换行(例如在三重引号字符串中),但是不能包含注释。 每个表达式会在格式化字符串字面值所包含的位置按照从左至右的顺序被求值。
在 3.7 版更改: 在 Python 3.7 之前, ef="https://docs.python.org/zh-cn/3/reference/compound_stmts.html#async-for">async for 子句的推导式不允许在格式化字符串字面值表达式中使用,这是因为具体实现存在一个问题。
如果指定了转换符,表达式的求值结果会先转换再格式化。转换符 '!s' 即对结果调用 str(),'!r' 为调用 repr(),而 '!a' 为调用 ascii()。
在此之后结果会使用 format() 协议进行格式化。格式说明符会被传入表达式或转换结果的 __format__() 方法。如果省略格式说明符则会传入一个空字符串。然后格式化结果会包含在整个字符串最终的值当中。
顶层的格式说明符可以包含有嵌套的替换字段。这些嵌套字段也可以包含有自己的转换字段和 格式说明符,但不可再包含更深层嵌套的替换字段。这里的 格式说明符微型语言 与字符串 .format() 方法所使用的相同。
格式化字符串字面值可以拼接,但是一个替换字段不能拆分到多个字面值。
一些格式化字符串字面值的示例:
>>>name = "Fred">>>f"He said his name is {name!r}." "He said his name is 'Fred'.">>>f"He said his name is {repr(name)}." # repr() is equivalent to !r "He said his name is 'Fred'.">>>width = 10>>>precision = 4>>>value = decimal.Decimal("12.34567")>>>f"result: {value:{width}.{precision}}" # nested fields 'result: 12.35'>>>today = datetime(year=2017, month=1, day=27)>>>f"{today:%B %d, %Y}" # using date format specifier 'January 27, 2017'>>>number = 1024>>>f"{number:#0x}" # using integer format specifier '0x400'
与正常字符串字面值采用相同语法导致的一个结果就是替换字段中的字符不能与外部的格式化字符串字面值所用的引号相冲突:
f"abc {a["x"]} def" # error: outer string literal ended prematurely f"abc {a['x']} def" # workaround: use different quoting
格式表达式中不允许有反斜杠,这会引发错误:
f"newline: {ord('\n')}" # raises SyntaxError
想包含需要用反斜杠转义的值,可以创建一个临时变量。
>>>newline = ord('\n')>>>f"newline: {newline}" 'newline: 10'
格式化字符串字面值不可用作文档字符串,即便其中没有包含表达式。
>>> deffoo():...f"Not a docstring"... >>>foo.__doc__is NoneTrue
另请参见 PEP 498 了解加入格式化字符串字面值的提议,以及使用了相关的格式字符串机制的 str.format()。
2.4.4. 数字字面值
数字字面值有三种类型: 整型数、浮点数和虚数。没有专门的复数字面值 (复数可由一个实数加一个虚数合成)。
注意数字字面值并不包含正负号;-1 这样的负数实际上是由单目运算符 '-' 和字面值 1 合成的。
2.4.5. 整型数字面值
整型数字面值由以下词法定义进行描述:
integerdecinteger::= 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"
整型数字面值的长度没有限制,能一直大到占满可用内存。
在确定数字大小时字面值中的下划线会被忽略。它们可用来将数码分组以提高可读性。一个下划线可放在数码之间,也可放在基数说明符例如 0x 之后。
注意非零的十进制数开头不允许有额外的零。这是为了避免与 Python 在版本 3.0 之前所使用的 C 风格八进制字面值相混淆。
一些整型数字面值的示例如下:
7 2147483647 0o177 0b100110111 3 79228162514264337593543950336 0o377 0xdeadbeef 100_000_000_000 0b_1110_0101
在 3.6 版更改: 允许在字面值中使用下划线进行分组。
2.4.6. 浮点数字面值
浮点数字面值由以下词法定义进行描述:
floatnumberpointfloatexponentfloatdigitpart::= digit (["_"] digit)*fractionexponent::= ("e" | "E") ["+" | "-"] digitpart
注意整型数部分和指数部分在解析时总是以 10 为基数。例如,077e010 是合法的,且表示的数值与 77e10 相同。浮点数字面值允许的范围依赖于具体实现。对于整型数字面值,支持以下划线进行分组。
一些浮点数字面值的示例如下:
3.14 10. .001 1e100 3.14e-10 0e0 3.14_15_93
在 3.6 版更改: 允许在字面值中使用下划线进行分组。
2.4.7. 虚数字面值
虚数字面值由以下词法定义进行描述:
imagnumber::= (floatnumber | digitpart) ("j" | "J")
一个虚数字面值将生成一个实部为 0.0 的复数。复数是以一对浮点数来表示的,它们的取值范围相同。要创建一个实部不为零的复数,就加上一个浮点数,例如 (3+4j)。一些虚数字面值的示例如下:
3.14j 10.j 10j .001j 1e100j 3.14e-10j 3.14_15_93j