ZetCode

Python f-string

最后修改于 2025 年 5 月 11 日

本 Python f-string 教程演示了如何使用 f-string 高效地格式化字符串,这是现代 Python 中字符串插值的首选方法。借助 f-string,开发人员可以以简洁直观的方式创建动态且可读性强的输出。

Python f-string 是 Python 3.6 中引入的一种强大而灵活的字符串格式化方法。与早期的格式化技术(如基于 % 的格式化和 str.format())不同,f-string 速度更快、可读性更强,并且不易出错。它们简化了字符串操作,同时保持了出色的性能。

f-string 以 f 前缀表示,并允许在花括号 {} 内嵌入表达式。这些表达式在运行时进行评估,使得 f-string 成为构造动态字符串的绝佳选择。例如:

name = "Alice"
age = 30
print(f"Hello, my name is {name} and I am {age} years old.")

在此示例中,Python 会自动将 {name}{age} 替换为它们对应的值。此功能使 f-string 比旧方法更直观,提高了代码的可读性。

f-string 还支持格式说明符,可控制数值精度、对齐和填充。格式说明符添加到花括号内的冒号 (:) 之后。例如,f'{price:.3f}' 确保存储在 price 中的浮点数四舍五入到小数点后三位。

price = 19.98765
formatted_price = f"{price:.3f}"
print(formatted_price) # Output: 19.988

除了基本格式化之外,f-string 还支持高级操作,例如内联计算、函数调用甚至条件表达式。这种多功能性使其适用于 Python 开发中的各种应用,从构造日志消息到格式化财务数据。

使用 f-string 可提高代码效率和可读性,同时降低字符串操作的复杂性。它们现在被认为是 Python 中格式化字符串的最佳实践,在大多数用例中取代了旧方法。

Python 字符串格式化

以下示例演示了在 Python 中格式化字符串的三种不同方法。它展示了从最旧的百分号样式格式化,到更现代的 str.format() 方法,最后到 Python 3.6 中引入的简洁而强大的 f-string 语法的发展。

main.py
#!/usr/bin/python

name = 'Peter'
age = 23

print('%s is %d years old' % (name, age))
print('{} is {} years old'.format(name, age))
print(f'{name} is {age} years old')

该示例使用两个变量格式化一个字符串。

print('%s is %d years old' % (name, age))

这是最旧的选项。它使用 % 运算符和经典的字符串格式说明符,如 %s%d

print('{} is {} years old'.format(name, age))

从 Python 3.0 开始,引入了 format 函数来提供高级格式化选项。

print(f'{name} is {age} years old')

Python f-string 自 Python 3.6 起可用。字符串具有 f 前缀,并使用 {} 来评估变量。

$ python main.py
Peter is 23 years old
Peter is 23 years old
Peter is 23 years old

表达式

下面的示例演示了如何在 f-string 中直接包含表达式。任何有效的 Python 表达式都可以放在花括号内,允许您在格式化输出时执行计算或操作数据。

main.py
#!/usr/bin/python

bags = 3
apples_in_bag = 12

print(f'There are total of {bags * apples_in_bag} apples')

在此,表达式 bags * apples_in_bag 在 f-string 中进行评估,其结果插入到输出中。这使得 f-string 在动态字符串构造方面非常灵活。

$ python main.py
There are total of 36 apples

使用字典

f-string 还可以访问字典中的值。您可以直接在花括号内引用字典键,从而轻松地在输出中显示结构化数据。

main.py
#!/usr/bin/python

user = {'name': 'John Doe', 'occupation': 'gardener'}

print(f"{user['name']} is a {user['occupation']}")

在此示例中,f-string 从字典中检索与 'name''occupation' 键关联的值,并将它们插入到输出字符串中。

$ python main.py
John Doe is a gardener

f-string 调试选项

Python 3.8 引入了一个方便的调试功能:自文档化表达式。通过在 f-string 中的表达式后添加等号 (=),Python 将打印表达式及其值,从而更轻松地跟踪计算和变量状态。

main.py
#!/usr/bin/python

import math

x = 0.8

print(f'{math.cos(x) = }')
print(f'{math.sin(x) = }')

此示例输出表达式及其结果,这对于调试或记录代码中的中间值特别有用。

$ python main.py
math.cos(x) = 0.6967067093471654
math.sin(x) = 0.7173560908995228

多行 f-string

f-string 可以跨越多行,从而可以轻松格式化较长的消息或文本块。您可以使用三引号创建多行 f-string,并在任何行上嵌入变量或表达式。

main.py
#!/usr/bin/python

name = 'John Doe'
occupation = 'gardener'
age = 34

msg = f'''name: {name}
age: {age}
occupation: {occupation}'''

print(msg)

此示例构造了一个包含多个变量的多行字符串。多行 f-string 对于生成格式化的报告或消息很有用。

$ python main.py
name: John Doe
age: 34
occupation: gardener

调用函数

您可以直接在 f-string 中调用函数。这允许您在行内显示函数调用的结果,使您的输出更加动态,并减少了对临时变量的需求。

main.py
#!/usr/bin/python

def mymax(x, y):

    return x if x > y else y

a = 3
b = 4

print(f'Max of {a} and {b} is {mymax(a, b)}')

在此,mymax 函数在 f-string 中被调用,其返回值包含在输出中。此技术有助于将计算结果直接呈现在字符串中。

$ python main.py
Max of 3 and 4 is 4

f-string 对象

f-string 还可以显示对象。如果对象定义了 __str____repr__ 方法,Python 将使用该方法将对象转换为字符串进行显示。这使得在输出中显示自定义对象变得容易。

main.py
#!/usr/bin/python

class User:
    def __init__(self, name, occupation):
        self.name = name
        self.occupation = occupation

    def __repr__(self):
        return f"{self.name} is a {self.occupation}"

u = User('John Doe', 'gardener')

print(f'{u}')

在此示例中,User 类定义了一个 __repr__ 方法。当对象在 f-string 中使用时,Python 会调用此方法来生成字符串表示。

$ python main.py
John Doe is a gardener

__format__ 方法

__format__ 方法允许您自定义对象在 f-string 中的格式。通过定义此方法,您可以根据 f-string 中提供的格式说明符来控制输出,从而为自定义类实现高级且灵活的格式化。

main.py
#!/usr/bin/python

from dataclasses import dataclass

@dataclass
class User:
    name: str
    occupation: str

    def __format__(self, spec):
        return f'User(name={self.name}{spec} occupation={self.occupation})'


u1 = User('John Doe', 'gardener')
u2 = User('Roger Roe', 'driver')
u3 = User('Lucia Smith', 'teacher')

print(f'{u1:-}')
print(f'{u2:;}')
print(f'{u3:#}')

在此示例中,__format__ 方法在对象的字段之间插入格式说明符。这种方法对于复杂应用程序中的自定义显示逻辑很有用。

$ python main.py
User(name=John Doe- occupation=gardener)
User(name=Roger Roe; occupation=driver)
User(name=Lucia Smith# occupation=teacher)

转义字符

有时您需要在 f-string 中包含特殊字符,例如花括号或引号。要做到这一点,您必须转义它们。花括号通过加倍来转义,单引号可以用反斜杠转义。

main.py
#!/usr/bin/python

print(f'Python uses {{}} to evaluate variables in f-strings')
print(f'This was a \'great\' film')

第一行显示如何在输出中显示花括号,而第二行演示了如何转义单引号。正确的转义可确保您的字符串按预期显示。

$ python main.py
Python uses {} to evaluate variables in f-strings
This was a 'great' film

Python f-string 格式化日期时间

f-string 可用于格式化日期和时间对象。通过在冒号后提供格式说明符,您可以控制 datetime 对象的输出,例如以自定义格式显示日期、时间、星期几或其他组件。

main.py
#!/usr/bin/python

import datetime

now = datetime.datetime.now()

print(f'{now:%Y-%m-%d %H:%M}')
print(f'{now:%A}')
print(f'{now:%a}')
print(f'{now:%B}')
print(f'{now:%j}')
print(f'{now:%w}')

此示例显示了使用 f-string 格式化当前日期和时间的几种方法。冒号后的格式代码遵循 strftime 方法的约定。

$ python main.py
2024-03-13 11:38
Wednesday
Wed
March
073
3

嵌套表达式

您可以在 f-string 中嵌套表达式,包括使用变量作为格式说明符。这允许高度动态的格式化,例如在运行时在不同的日期格式或其他输出样式之间切换。

main.py
#!/usr/bin/python

from datetime import datetime

today = datetime.now().date()

spec1 = '%d.%m.%y'
spec2 = '%y/%m/%d'

print(f'{today:{spec1}}')
print(f'{today:{spec2}}')

在此,格式说明符存储在变量中,然后在 f-string 中使用。此技术对于创建灵活且可重用的格式化代码很有用。

$ python main.py
16.03.24
24/03/16

格式化浮点数

f-string 可以轻松控制显示浮点数时的小数位数。您可以直接在冒号后指定精度,确保您的输出尽可能精确或简洁。

main.py
#!/usr/bin/python

val = 12.3

print(f'{val:.2f}')
print(f'{val:.5f}')

第一行打印小数点后两位的数值,第二行显示小数点后五位的数值。这在精度很重要的财务或科学应用中尤其有用。

$ python main.py
12.30
12.30000

千位分隔符

您可以使用 f-string 为大数添加千位分隔符,使其更易于阅读。下划线和逗号都支持作为分组字符,这有助于显示财务、统计或科学数据。

main.py
#!/usr/bin/python

val = 1_200_400_001

print(val)
print(f'{val:_}')
print(f'{val:,}')

输出显示了数字的原始形式、带下划线的形式以及带逗号的形式。这使得一次性解析大值更加容易。

$ python main.py
1200400001
1_200_400_001
1,200,400,001

百分比

f-string 也可用于显示百分比。通过使用百分比格式说明符 (%),您可以轻松地将十进制值转换为百分比,并且可以控制显示的位数。

main.py
#!/usr/bin/python

val = 1/7.0

print(f'{val}')
print(f'{val:.2%}')

第一行打印原始十进制值,第二行将其显示为带两位小数的百分比。这对于报告和数据分析很有用。

$ python main.py 
0.14285714285714285
14.29%

格式宽度

您可以在 f-string 中设置格式化值的宽度,这对于在表格或报告中对齐列非常有用。您还可以指定填充字符(如零)来填充短于所需宽度的值。

main.py
#!/usr/bin/python

for x in range(1, 11):
    print(f'{x:02} {x*x:3} {x*x*x:4}')

此示例打印三列:第一列填充零至两位数,第二列右对齐至三个空格,第三列右对齐至四个空格。这种方法非常适合创建格式整齐的表格。

$ python main.py
01   1    1
02   4    8
03   9   27
04  16   64
05  25  125
06  36  216
07  49  343
08  64  512
09  81  729
10 100 1000

对齐字符串

f-string 允许您在给定宽度内将字符串左对齐、右对齐或居中对齐。这由冒号之后的 ><^ 字符控制。对齐对于在表格或输出中对齐文本非常有用。

main.py
#!/usr/bin/python

words = ['sky', 'fork', 'small', 'cup', 'car', 'war']

for word in words:
    print(f'|{word:>20}|')

for word in words:
    print(f'|{word:^20}|')

for word in words:
    print(f'|{word:<20}|')

第一个循环右对齐每个单词,第二个居中对齐,第三个左对齐。每行输出的宽度恰好为 20 个字符,从而可以轻松创建对齐的文本列。

$ python main.py
|                 sky|
|                fork|
|               small|
|                 cup|
|                 car|
|                 war|
|        sky         |
|        fork        |
|       small        |
|        cup         |
|        car         |
|        war         |
|sky                 |
|fork                |
|small               |
|cup                 |
|car                 |
|war                 |

数字表示法

f-string 可以以多种表示法显示数字,包括十六进制、八进制、二进制和科学计数法。这对于调试、数据分析或处理不同的数字系统非常有用。

main.py
#!/usr/bin/python

val = 300

# hexadecimal lower
print(f'{val:x}')

# hexadecimal upper
print(f'{val:X}')

# octal
print(f'{val:o}')

# binary
print(f'{val:b}')

# scientific
print(f'{val:e}')

此示例以几种不同的表示法打印相同的值,展示了使用 f-string 轻松切换格式。

$ python main.py
12c
12C
454
100101100
3.000000e+02

使用 f-string 格式化字节和字节数组

Python 的 f-string 支持对 bytesbytearray 对象进行直接格式化,从而可以在字符串输出中高效地表示二进制数据。这在处理编码数据、网络数据包或文件处理时很有用。

main.py
#!/usr/bin/python

data = b'\x48\x65\x6c\x6c\x6f'  # Byte sequence representing "Hello"
byte_array = bytearray([72, 101, 108, 108, 111])  # Equivalent bytearray

print(f"Bytes (hex): {data.hex()}")  # Output: 48656c6c6f
print(f"Bytearray (ASCII): {byte_array.decode()}")  # Output: Hello

f-string 通过 hex 实现 bytes 对象到十六进制表示的直接转换,而 bytearray 支持使用 decode 解码为可读文本。这些方法增强了二进制数据在格式化输出中的可用性。

格式化枚举

Python 的 Enum 类允许定义符号常量,而 f-string 提供了一种直观的方式来格式化和显示其值。枚举可以由其名称或分配的值表示。

main.py
#!/usr/bin/python

from enum import Enum

class Status(Enum):
    SUCCESS = 1
    FAILURE = 2
    PENDING = 3

status = Status.SUCCESS

print(f"Status name: {status.name}")  # Output: SUCCESS
print(f"Status value: {status.value}")  # Output: 1

使用 f-string,可以通过访问枚举成员的 .name.value 属性来动态格式化它们,从而在需要结构化常量的应用程序中确保有意义的输出。

Unicode 和特殊字符

Python f-string 完全支持 Unicode,这意味着您可以轻松地在格式化输出中包含非 ASCII 字符、带重音的字母甚至表情符号。这对于国际化或当您想在字符串中显示特殊符号时特别有用。

main.py
#!/usr/bin/python

name = "Zoë"
emoji = "\U0001F600"  # 😀
print(f"User: {name} {emoji}")

在此示例中,f-string 将名称与带重音的字符和表情符号结合在一起。f-string 原生处理这些字符,确保在终端或应用程序中正确渲染和输出。

格式化数字:前导零和数字分组

f-string 提供了强大的数字格式化选项。您可以为数字填充前导零以确保固定宽度输出,或使用逗号作为千位分隔符使大数更易于阅读。这些功能对于报告、表格或任何需要对齐和清晰度的输出特别有用。

main.py
#!/usr/bin/python

number = 42
big_number = 1234567

print(f"{number:05}")      # Output: 00042 (5-digit width, zero-padded)
print(f"{big_number:,}")   # Output: 1,234,567 (comma as a thousands separator)

用零填充可确保数字在列中对齐,而使用逗号对数字进行分组可提高大值的可读性。花括号内的冒号 (:) 允许您直接在 f-string 中指定这些格式化选项。

使用列表推导式和 lambda 函数

f-string 可以在花括号内评估任何有效的 Python 表达式。这包括列表推导式和 lambda 函数,允许您即时生成和显示动态内容。此功能对于快速显示计算结果或摘要而无需额外代码非常有用。

main.py
#!/usr/bin/python

nums = [1, 2, 3]
print(f"Squares: {[x**2 for x in nums]}")  # List comprehension inside f-string

add = lambda a, b: a + b
print(f"Sum: {add(5, 7)}")  # Lambda function execution inside f-string

通过嵌入列表推导式或 lambda 调用等表达式,您可以在单个 f-string 中生成简洁、可读的输出,这些输出反映了实时计算或数据转换。

变量的动态宽度和精度

f-string 允许您使用变量而不是硬编码值来动态设置格式化输出的宽度和精度。当您需要根据运行时条件或用户偏好调整格式时,这提供了极大的灵活性。

main.py
#!/usr/bin/python

value = 123.456789
width = 10
precision = 3

# Dynamic width and precision using variables
print(f"Fixed format:    {value:{width}.{precision}f}")

# Adjust precision based on the value
large_value = 12345.6789
precision = 1 if large_value > 10000 else 3
print(f"Adaptive format: {large_value:.{precision}f}")

第一个示例同时使用了宽度和精度的变量,允许您以编程方式控制格式化参数。第二个示例演示了如何根据值的幅度更改精度,这对于在值具有不同比例时保持输出一致性很有用。

$ python main.py
Fixed format:       123.457
Adaptive format: 12345.7

自定义填充字符和对齐方式

f-string 支持在对齐文本时用于填充的自定义填充字符。除了空格或零之外,您还可以使用任何字符来填充额外空间,这对于创建视觉分隔符或装饰性输出很有用。

main.py
#!/usr/bin/python

title = "TITLE"

# Center with asterisks
print(f"{title:*^30}")

# Right-align with dashes
print(f"{title:->30}")

# Left-align with dots
print(f"{title:.<30}")

# Numbers can use custom fill characters too
number = 42
print(f"{number:#>10}")

语法是 {value:fill_char align width},其中 fill_char 是任何单个字符,align 是 ^(居中)、>(右对齐)或 <(左对齐)之一,width 是总字段宽度。这使您可以精确控制输出的外观。

$ python main.py
************TITLE************
------------------------TITLE
TITLE........................
########42

使用符号控制格式化数字

f-string 提供对正数和负数显示方式的精确控制,包括是否显示正数的加号。这对于财务报告、科学计数法以及数字符号很重要的任何上下文都至关重要。

main.py
#!/usr/bin/python

positive = 42
negative = -42
zero = 0

# Always show the sign (+ or -)
print(f"Always show sign:  {positive:+d} {negative:+d} {zero:+d}")

# Only show the - sign for negative numbers (default)
print(f"Default behavior:  {positive:d} {negative:d} {zero:d}")

# Show space for positive, - for negative (useful for alignment)
print(f"Space for positive: {positive: d} {negative: d} {zero: d}")

# Combine with width for aligned columns
print(f"Aligned column:    {positive:+5d} {negative:+5d} {zero:+5d}")

+ 标志确保同时显示正号和负号,这对于可能为正或负的数据很有用。空格标志 ( ) 为符号保留空间,但仅对负值显示,有助于保持列对齐,同时减少混乱。

$ python main.py
Always show sign:  +42 -42 +0
Default behavior:  42 -42 0
Space for positive:  42 -42  0
Aligned column:    +42   -42    +0

格式化复数

f-string 还可以格式化复数,允许您控制实部和虚部的显示。如果需要,您可以为两个部分分别指定精度,尽管标准的浮点格式化选项仍然适用。

main.py
#!/usr/bin/python

c = 3.14159 + 2.71828j

# Default formatting
print(f"Default: {c}")

# Format with precision for both parts
print(f"Precision: {c:.2f}")

# Accessing real and imaginary parts separately
print(f"Real: {c.real:.3f}, Imaginary: {c.imag:.3f}j")

{c:.2f} 中的 .2f 说明符适用于复数的实部和虚部。您也可以分别访问和格式化 .real.imag 属性,以获得更精细的控制。

$ python main.py
Default: (3.14159+2.71828j)
Precision: (3.14+2.72j)
Real: 3.142, Imaginary: 2.718j

嵌套 f-string

f-string 可以嵌套,这意味着一个 f-string 可以是另一个 f-string 中表达式的一部分。这允许进行复杂的动态字符串构造,但重要的是要注意不要过度使用深度嵌套以保持可读性。

main.py
#!/usr/bin/python

name = "there"
precision = 2
value = 3.14159

# Nested f-string to dynamically set precision
print(f"Hello, {name}! Value: {value:.{precision}f}")

# Another example with a conditional expression
price = 49.99
print(f"Item: {"Book"}, Price: ${f"{price:.2f}" if price > 0 else "Free"}")

在第一个示例中,{value:.{precision}f} 中的 {precision} 展示了内部 f-string 表达式如何为外部表达式定义格式说明符。第二个示例展示了一个 f-string 在主 f-string 内的条件表达式中的用法。

$ python main.py
Hello, there! Value: 3.14
Item: Book, Price: $49.99

来源

Python f-string - 语言参考

在本文中,我们学习了 Python f-string。

作者

我的名字是 Jan Bodnar,我是一名充满激情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有 Python 教程