python3 f-strings格式字符串

从Python3.6开始,f-string提供了一种更简洁、易读且高效的字符串格式化方法,取代了传统的%-formatting和str.format()。本文详细介绍了f-string的语法、特性及优势,包括表达式的灵活运用、多行字符串的支持以及性能对比。

从Python 3.6开始,f-string是格式化字符串的一种很好的新方法。与其他格式化方式相比,它们不仅更易读,更简洁,不易出错,而且速度更快!

今天就开始使用f-string(后文称为F字符串) !

首先, 我们要聊以下在F字符串出现之前我们怎么实现格式化字符的。

 

旧时代的格式化字符串

在Python 3.6之前,有两种将Python表达式嵌入到字符串文本中进行格式化的主要方法:%-formattingstr.format()。您即将看到如何使用它们以及它们的局限性。

#1: %-formatting

这是Python格式化的OG(original generation),伴随着python语言的诞生。可以在Python文档中阅读更多内容。请记住,文档不建议使用%格式,其中包含以下注释:

“The formatting operations described here exhibit a variety of quirks that lead to a number of common errors (such as failing to display tuples and dictionaries correctly).

Using the newer formatted string literals or the str.format() interface helps avoid these errors. These alternatives also provide more powerful, flexible and extensible approaches to formatting text.”

怎样使用 %-formatting

字符串对象具有使用%运算符的内置操作,可以使用它来格式化字符串。

name = "Eric"
"Hello, %s." % name

# 输出
'Hello, Eric.'

为了插入多个变量,必须使用这些变量的元组。以

name = "Eric"
age = 74
"Hello, %s. You are %s." % (name, age)

# 输出
'Hello, Eric. You are 74.'

为什么 %-formatting不好用

上面的代码示例足够易读。但是,一旦你开始使用几个参数和更长的字符串,将很快变得不太容易阅读。

first_name = "Eric"
last_name = "Idle"
age = 74
profession = "comedian"
affiliation = "Monty Python"
"Hello, %s %s. You are %s. You are a %s. You were a member of %s." %</div>
(first_name, last_name, age, profession, affiliation)

# 输出
'Hello, Eric Idle. You are 74. You are a comedian. You were a member of Monty Python.'

这种格式不是很好,因为它是冗长的,会导致错误,比如不能正确显示元组或字典。

#2: str.format()

这种更新的工作方式是在Python 2.6中引入的。

怎样使用Use str.format()

str.format()是对%-formatting的改进。它使用正常的函数调用语法,并且可以通过对要转换为字符串的对象的__format __()方法进行扩展。

使用str.format(),替换字段用大括号标记:

"Hello, {}. You are {}.".format(name, age)

# 输出
'Hello, Eric. You are 74.'

通过引用其索引来以任何顺序引用变量:

"Hello, {1}. You are {0}-{0}.".format(age, name)

# 输出
'Hello, Eric. You are 74-74.'

但是,如果插入变量名称,则会获得额外的能够传递对象的权限,然后在大括号之间引用参数和方法:

person = {'name': 'Eric', 'age': 74}
"Hello, {name}. You are {age}.".format(name=person['name'], age=person['age'])

# 输出
'Hello, Eric. You are 74.'

也可以使用**来用字典来完成这个巧妙的技巧:

"Hello, {name}. You are {age}.".format(**person)

# 输出
'Hello, Eric. You are 74.'

f-string相比,str.format()绝对是一个升级版本,但它并非总是好的。

为什么 str.format() 并不好

使用str.format()的代码比使用%-formatting的代码更易读,但当处理多个参数和更长的字符串时,str.format()仍然可能非常冗长。

first_name = "Eric"

last_name = "Idle"

age = 74

profession = "comedian"

affiliation = "Monty Python"

print(("Hello, {first_name} {last_name}. You are {age}. " + 

       "You are a {profession}. You were a member of {affiliation}.") </div>

       .format(first_name=first_name, last_name=last_name, age=age, </div>
               profession=profession, affiliation=affiliation))

# 输出
Hello, Eric Idle. You are 74. You are a comedian. You were a member of Monty Python.

如果想要传递给字典中的.format()的变量,那么你可以用.format(** some_dict)解压缩它,并通过字符串中的键引用这些值,但是必须有更好的的方法

 

f-Strings:一种改进Python格式字符串的新方法

F字符串在这里可以节省很多的时间。他们确实使格式化更容易。他们自Python 3.6开始加入标准库。

也称为“格式化字符串文字”,F字符串是开头有一个f的字符串文字,以及包含表达式的大括号将被其值替换。表达式在运行时进行渲染,然后使用__format__协议进行格式化。与

以下是f-strings可以让编程更轻松的一些方法。

简单例子

语法与str.format()使用的语法类似,但较少细节啰嗦。

name = "Eric"
age = 74
f"Hello, {name}. You are {age}."

# 输出
'Hello, Eric. You are 74.'

使用大写字母F也是有效的:

F"Hello, {name}. You are {age}."

# 输出
'Hello, Eric. You are 74.'

任意表达式

由于f字符串是在运行时进行渲染的,因此可以将任何有效的Python表达式放入其中。

可以做一些非常简单的事情,就像这样:

f"{2 * 37}"

# 输出
'74'

可以调用函数

f"{name.lower()} is funny."

# 输出
'eric is funny.'

甚至可以使用带有f字符串的类创建对象。

class Comedian:
    def __init__(self, first_name, last_name, age):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age

    def __str__(self):
        return f"{self.first_name} {self.last_name} is {self.age}."

    def __repr__(self):
        return f"{self.first_name} {self.last_name} is {self.age}. Surprise!"
    
new_comedian = Comedian("Eric", "Idle", "74")
f"{new_comedian}"

'Eric Idle is 74.'

__str __()__repr __()方法处理对象如何呈现为字符串,因此您需要确保在类定义中包含至少一个这些方法。如果必须选择一个,请使用__repr __(),因为它可以代替__str __()

__str __()返回的字符串是对象的非正式字符串表示,应该可读。__repr __()返回的字符串是官方表示,应该是明确的。调用str()repr()比直接使用__str __()__repr __()更好。

默认情况下,f字符串将使用__str __(),但如果包含转换标志!r,则可以确保它们使用__repr __()

f"{new_comedian}"
'Eric Idle is 74.'

f"{new_comedian!r}"
'Eric Idle is 74. Surprise!'

多行f-string  多行字符串

message = (f"Hi {name}. "
        f"You are a {profession}. "
        f"You were in {affiliation}.")
message

# 输出
'Hi Eric. You are a comedian. You were in Monty Python.'

没必要将f放在多行字符串的每一行的前面。以下代码也能运行:

message = (f"Hi {name}. "
        "You are a {profession}. "
        "You were in {affiliation}.")
message

# 输出
'Hi Eric. You are a {profession}. You were in {affiliation}.'

但是如果使用"""这将会发生什么:

message = f"""
    Hi {name}. 
    You are a {profession}. 
    You were in {affiliation}.
 """

message

# 输出
'\n    Hi Eric. \n    You are a comedian. \n    You were in Monty Python.\n '

性能

f字符串中的f也可以代表“速度快”。

f-字符串比%-formattingstr.format()都快。f-字符串是运行时渲染的表达式,而不是常量值。以下是文档摘录:

“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.” (Source)

在运行时,大括号内的表达式将在其自己的作用域中进行求值,然后将其与其余字符串组合在一起。

以下是速度比较:

%%timeit
name = "Eric" 
age = 74 
'%s is %s.' % (name, age)

202 ns ± 2.05 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%%timeit
name = "Eric" 
age = 74 
'{} is {}.'.format(name, age)

244 ns ± 5.52 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%%timeit
name = "Eric" 
age = 74 
f'{name} is {age}.'

14.4 ns ± 0.0121 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

可以看到, 速度最快的就是f字符串.

 

Python f-Strings:Pesky细节

为什么F字符串很好,开始使用它们但请记住一些细节。

引号

您可以在表达式中使用各种类型的引号。只要确保在表达式中使用的f-字符串外部没有使用相同类型的引号即可。

以下写法都是正确的:

f"{'Eric Idle'}"

'Eric Idle'



f'{"Eric Idle"}'

'Eric Idle'



f"""Eric Idle"""

'Eric Idle'



f'''Eric Idle'''

'Eric Idle'



f"The \"comedian<span class="string">" is {name}, aged {age}."

'The "comedian" is Eric, aged 74.'

字典

说在使用字典的时候。如果要为字典的键使用单引号,请记住确保对包含键的f字符串使用双引号。

以下代码是有效的:

comedian = {'name': 'Eric Idle', 'age': 74}
f"The comedian is {comedian['name']}, aged {comedian['age']}."

# 输出
'The comedian is Eric Idle, aged 74.'

但是,以下代码就是一个语法错误:

f'The comedian is {comedian['name']}, aged {comedian['age']}.'

# 输出
  File "&lt;ipython-input-40-cd7d8a3db23b&gt;", line 1
    f'The comedian is {comedian['name']}, aged {comedian['age']}.'
                                    ^
SyntaxError: invalid syntax

字典键周围使用与在f字符串外部使用相同类型的引号,则第一个字典键开头的引号将被解释为字符串的结尾。

大括号

为了使字符串出现大括号,您必须使用双大括号:

f"{{74}}"

'{74}'

但是,如果使用三个以上的大括号,则可以获得更多大括号:

f"{{{{74}}}}"

'{{74}}'

反斜杠

正如之前所看到的,可以在f字符串的字符串部分使用反斜杠转义符。但是,不能使用反斜杠在f字符串的表达式部分中进行转义:

f"{<span class="string">"Eric Idle\"}"

# 输出
  File "&lt;ipython-input-43-35cb9fe0ccc1&gt;", line 1
    f"{\"Eric Idle\"}"
                      ^
SyntaxError: f-string expression part cannot include a backslash

lambda表达式

如果需要使用lambda表达式,解析f-字符串的方式会稍微复杂一些。

如果!, :}不在括号,大括号,括号或字符串中,则它将被解释为表达式的结尾。由于lambda使用,这可能会导致一些问题:

f"{lambda x: x * 37 (2)}"

# 输出
  File "&lt;fstring&gt;", line 1
    (lambda x)
             ^
SyntaxError: unexpected EOF while parsing

可以通过将您的lambda嵌套在圆括号中来解决此问题:

f"{(lambda x: x * 37) (2)}"

# 输出
'74'

虽然仍然可以使用格式化字符串的较旧方式,但使用F字符串时可以更简洁,更易读且更方便的方式,既快速又不易出错。

 

<think>嗯,用户之前问过关于Python字符串格式化和f-strings的问题,现在他们又提到“Python的f-strings格式化对照表”,可能希望得到一个更详细的结构化总结。我需要确保覆盖所有常见的格式说明符,并提供实用的代码示例。首先,我需要回顾用户之前的问题和回答。之前的回答已经包括了数字格式化的对照表,但这次用户可能想要更全面的,包括字符串、数字、日期等。可能需要分类型整理,比如整数、浮点数、字符串对齐、日期时间等。 用户可能还希望看到实际应用场景的例子,比如财务数据、科学计数或者日志记录中的使用。此外,注意用户提到“对照表”,可能需要表格形式,方便查阅。需要检查是否有遗漏的格式符,比如二进制、八进制、十六进制,以及千位分隔符的使用。同时,考虑对齐方式(左对齐、右对齐、居中)和填充字符的设置。动态格式化的例子也很重要,比如在运行时决定精度或宽度。 还要注意特殊案例,比如处理大数字时的科学计数法,或者自定义对象的格式化方法。另外,安全问题虽然之前提到过,但这里可能不需要重复,除非用户特别指出。 用户可能没有明确提到,但可能对如何在f-string中处理多语言或本地化设置感兴趣,比如千位分隔符的不同表示方法。或者如何在格式化中包含变量名,比如f-strings的=操作符,这在调试中很有用。 最后,确保代码示例简洁明了,每个例子都展示不同的格式选项,并注释输出结果。这样用户可以直接复制代码测试,理解每个参数的作用。可能还需要提醒用户注意Python版本,因为某些格式特性可能在旧版本中不可用。例如,f-strings3.6+才有,而某些格式选项可能在后续版本中添加。总结:需要分门别类整理格式说明符,提供实用示例,覆盖各种数据类型和常见应用场景,确保信息结构清晰,方便用户快速查找和参考。</think>以下是Python f-strings格式化功能的完整对照表及工程实践指南: --- ### 一、通用格式语法 ```python f"{value:[填充][对齐][符号][#][0][宽度][千分位][.精度][类型]}" ``` --- ### 二、核心格式化对照表 #### 1. 字符串格式化 | 格式规范 | 示例 | 输出 | |---------|------|-----| | `<` 左对齐 | `f"{&#39;text&#39;:<10}"` | `text ` | | `>` 右对齐 | `f"{3.14:>10}"` | ` 3.14` | | `^` 居中对齐 | `f"{&#39;center&#39;:^10}"` | ` center ` | | `填充字符` | `f"{&#39;alert&#39;:*^10}"` | `**alert***` | #### 2. 数值类型格式化 | 类型 | 格式符 | 示例 | 输出 | |------|--------|------|-----| | 整数 | `d` | `f"{42:04d}"` | `0042` | | 浮点数 | `f` | `f"{3.1415:.2f}"` | `3.14` | | 科学计数 | `e` | `f"{0.001:.2e}"` | `1.00e-03` | | 百分比 | `%` | `f"{0.875:.1%}"` | `87.5%` | | 二进制 | `b` | `f"{10:#b}"` | `0b1010` | | 十六进制 | `x` | `f"{255:#04x}"` | `0xff` | #### 3. 特殊数值处理 | 功能 | 格式规范 | 示例 | 输出 | |------|----------|------|-----| | 千分位 | `,` | `f"{1234567:,}"` | `1,234,567` | | 符号控制 | `+` | `f"{-42:+}"` | `-42` | | 正数空格 | ` ` | `f"{42: }"` | ` 42` | | 进制前缀 | `#` | `f"{15:#o}"` | `0o17` | #### 4. 日期时间格式化 ```python from datetime import datetime now = datetime.now() print(f"{now:%Y-%m-%d %H:%M:%S}") # 2024-07-15 14:30:00 ``` --- ### 三、高级用法示例 #### 1. 动态格式参数 ```python def format_temp(temp, unit=&#39;C&#39;): return f"{temp:.1f}°{unit}" print(format_temp(23.456)) # 23.5°C ``` #### 2. 嵌套格式化 ```python width = 10 prec = 3 value = 3.1415926 print(f"Pi: {value:{width}.{prec}f}") # Pi: 3.142 ``` #### 3. 表达式计算 ```python items = [("Apple", 1.99), ("Banana", 0.79)] for name, price in items: print(f"{name.upper():<8} ${price * 1.1:.2f}") # 含税价格 ``` #### 4. 调试模式(Python 3.8+) ```python x = 42 print(f"{x=} {x*2=}") # x=42 x*2=84 ``` --- ### 四、工程实践案例 #### 1. 财务报告 ```python transactions = [ ("2024-Q1", 1234567.89), ("2024-Q2", 2345678.12) ] for period, amount in transactions: print(f"{period} | ${amount:>15,.2f}") # 输出: # 2024-Q1 | $ 1,234,567.89 # 2024-Q2 | $ 2,345,678.12 ``` #### 2. 内存地址显示 ```python def format_address(addr, bits=64): return f"0x{addr:0{bits//4}x}" print(format_address(0xdeadbeef)) # 0x00000000deadbeef ``` #### 3. 科学实验数据 ```python data = { "temperature": 23.456, "pressure": 101325, "voltage": 3.141592e-3 } for k, v in data.items(): print(f"{k.upper():<12} {v:#.4g}") # TEMPERATURE 23.46 # PRESSURE 1.013e+05 # VOLTAGE 3.142e-03 ``` --- ### 五、格式规范速查卡 | 场景 | 格式模式 | 示例输出 | |------|----------|----------| | 财务金额 | `f"${value:,.2f}"` | $1,234.56 | | 内存地址 | `f"0x{addr:08x}"` | 0x0000abcd | | 科学计数 | `f"{0.000314:.3e}"` | 3.140e-04 | | 进度显示 | `f"{current/total:.1%}"` | 75.5% | | 对齐填充 | `f"{&#39;ERROR&#39;:#^20}"` | #####ERROR##### |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值