文档章节

python f-string 字符串格式化

 阿豪boy
发布于 06/24 23:44
字数 2914
阅读 28
收藏 4
点赞 0
评论 0

主要内容

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

在本文的最后,您将了解如何以及为什么今天开始使用f-string(后文称为F字符串)。

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

旧时代的格式化字符串

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

Option #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

字符串对象具有使用%运算符的内置操作,您可以使用它来格式化字符串。以下是实践中的情况:

 

1

2

 

name = "Eric"

"Hello, %s." % name

'Hello, Eric.'

为了插入多个变量,您必须使用这些变量的元组。以下是你如何做到这一点:

 

1

2

3

 

name = "Eric"

age = 74

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

'Hello, Eric. You are 74.'

为什么 %-formatting不好用

上面刚刚看到的代码示例足够易读。但是,一旦你开始使用几个参数和更长的字符串,你的代码将很快变得不太容易阅读。事情已经开始显得有点凌乱:

 

1

2

3

4

5

6

7

 

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." %\

(first_name, last_name, age, profession, affiliation)

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

不幸的是,这种格式不是很好,因为它是冗长的,会导致错误,比如不能正确显示元组或字典。幸运的是,未来有更光明的日子。

Option #2: str.format()

这种更新的工作方式是在Python 2.6中引入的。您可以查看Python文档以获取更多信息。

怎样使用Use str.format()

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

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

 

1

 

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

'Hello, Eric. You are 74.'

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

 

1

 

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

'Hello, Eric. You are 74-74.'

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

 

1

2

 

person = {'name': 'Eric', 'age': 74}

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

'Hello, Eric. You are 74.'

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

 

1

 

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

'Hello, Eric. You are 74.'

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

为什么 str.format() 并不好

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

 

1

2

3

4

5

6

7

8

9

 

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}.") \

.format(first_name=first_name, last_name=last_name, age=age, \

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开始加入标准库。您可以在PEP 498中阅读所有内容。

也称为“格式化字符串文字”,F字符串是开头有一个f的字符串文字,以及包含表达式的大括号将被其值替换。表达式在运行时进行渲染,然后使用__format__协议进行格式化。与往常一样,Python文档是您想要了解更多信息的最佳读物。

以下是f-strings可以让你的生活更轻松的一些方法。

简单例子

语法与str.format()使用的语法类似,但较少细节啰嗦。看看这是多么容易可读:

 

1

2

3

 

name = "Eric"

age = 74

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

'Hello, Eric. You are 74.'

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

 

1

 

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

'Hello, Eric. You are 74.'

你喜欢F格式化字符串吗?我希望在本文的最后,你会回答>>> F"{Yes!}"

任意表达式

由于f字符串是在运行时进行渲染的,因此可以将任何有效的Python表达式放入其中。这可以让你做一些漂亮的事情。

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

 

1

 

f"{2 * 37}"

'74'

你可以调用函数

 

1

 

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

'eric is funny.'

你甚至可以使用带有f字符串的类创建对象。想象一下你有以下类:

 

1

2

3

4

5

6

7

8

9

10

11

 

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!"

 

1

2

 

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 __()

 

1

 

f"{new_comedian}"

'Eric Idle is 74.'
 

1

 

f"{new_comedian!r}"

'Eric Idle is 74. Surprise!'

多行f-string

你可以有多行字符串:

 

1

2

3

4

 

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放在多行字符串的每一行的前面。以下代码也能work:

 

1

2

3

4

 

message = (f"Hi {name}. "

"You are a {profession}. "

"You were in {affiliation}.")

message

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

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

 

1

2

3

4

5

6

7

 

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)

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

以下是速度比较:

 

1

2

3

4

 

%%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)
 

1

2

3

4

 

%%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)
 

1

2

3

4

 

%%timeit

name = "Eric"

age = 74

'{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-字符串外部没有使用相同类型的引号即可。

以下写法都是正确的:

 

1

 

f"{'Eric Idle'}"

'Eric Idle'
 

1

 

f'{"Eric Idle"}'

'Eric Idle'
 

1

 

f"""Eric Idle"""

'Eric Idle'
 

1

 

f'''Eric Idle'''

'Eric Idle'
 

1

 

f"The \"comedian\" is {name}, aged {age}."

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

字典

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

以下代码是有效的:

 

1

2

 

comedian = {'name': 'Eric Idle', 'age': 74}

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

'The comedian is Eric Idle, aged 74.'

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

 

1

 

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

  File "<ipython-input-40-cd7d8a3db23b>", line 1
    f'The comedian is {comedian['name']}, aged {comedian['age']}.'
                                    ^
SyntaxError: invalid syntax

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

大括号

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

 

1

 

f"{{74}}"

'{74}'

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

 

1

 

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

'{{74}}'

反斜杠

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

 

1

 

f"{\"Eric Idle\"}"

  File "<ipython-input-43-35cb9fe0ccc1>", line 1
    f"{\"Eric Idle\"}"
                      ^
SyntaxError: f-string expression part cannot include a backslash

lambda表达式

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

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

 

1

 

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

  File "<fstring>", line 1
    (lambda x)
             ^
SyntaxError: unexpected EOF while parsing

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

 

1

 

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

'74'

结束语

您仍然可以使用格式化字符串的较旧方式,但使用F字符串时,您现在可以使用更简洁,更易读且更方便的方式,既快速又不易出错。如果您尚未进行切换,则使用Python 3.6简化您的生活是开始使用Python 3.6的重要原因。 (如果您仍在使用Python 2,请不要忘记2020年即将到来!)

根据Python的哲学,当你需要决定如何做某事时,那么“这里应该是一个 - 并且最好只有一个 - 明显的方法来做到这一点”。尽管F字符串不是唯一可能的方式为了格式化字符串,他们很有可能成为完成工作的一种明显方式。

注意

本文转载自:http://www.mlln.cn/2018/05/19/python3%20f-string%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%AD%97%E7%AC%A6%E4%...

共有 人打赏支持
粉丝 21
博文 970
码字总数 665166
作品 0
西安
Python入门(十四) 字符串

Python中的字符串可以是单引号''或者双引号""括起来,如果字符串比较长,需要垮行,可以使用三引号''' ''' errHtml = '''<HTML><HEAD><TITLE>Python CGI Demo</TITLE></HEAD><BODY><H3>ERROR......

kaedehao
2015/08/19
0
0
python字符串格式化输出及相关操作代码举例

字符串的格式化 Python 支持格式化字符串的输出 。尽管这样可能会用到非常复杂的表达式,但最基本的用法是将一个值插入到一个有字符串格式符 %s 的字符串中。在 Python 中,字符串格式化使用...

小星星程序员
2014/08/15
0
0
Python字符串格式化 (%操作符)

在许多编程语言中都包含有格式化字符串的功能,比如C和Fortran语言中的格式化输入输出。Python中内置有对字符串进行格式化的操作%。 模板 格式化字符串时,Python使用一个字符串作为模板。模...

若虚道人
2014/07/07
0
0
《Python从小白到大牛》第6章 数据类型

在声明变量时会用到数据类型,在前面已经用到一些数据类型,例如整数和字符串等。在Python中所有的数据类型都是类,每一个变量都是类的“实例”。没有基本数据类型的概念,所以整数、浮点和字...

tony关东升
07/09
0
0
Python3.6中那些很酷的特性

你还记得 3.6 有哪些酷炫的特性吗?来回顾一下。 可读性更强的数字字面值 Python代码在可读性上做到了极致,被称为是可执行伪代码。然而,它还在不断地改进,比如这个可读性更好的数字字面值...

技术小能手
07/16
0
0
python学习笔记四:字符串格式化

字符串格式化:%,左侧放字符串,右侧放希望被格式化的值,通常为元组 >>> format = "Hello, %s, %s enough for ya?" >>> values = ('world', 'Hot') >>> print format % values Hello, wor......

笑看天空
06/26
0
0
#python+java#同样功能的代码两种语言实现

概述:设置两个数组/列表,列表a是[1,2,3],列表b是['a','b','c'],把他们一对一对打印出来,但不打印“3:c”这对。 python版: '''Created on 2014-11-2@author: Administrator'''class My...

Hochikong
2014/11/02
0
0
走进Python世界(五)数据类型 2. 字符串(String)

字符串String 使用引号定义的一组可以包含数字,字母,符号(非特殊系统符号)的集合。 如: Strval=“This is a test!”Strval1='This is a test!'Strval2="""This is a test""" 三重引号(...

Garrry
2015/07/20
0
0
Python基础班每日整理(二)

02Python基础day02 Python中注释的作用?单行和多行注释 在程序中对某些代码进行标注说明,增强程序的可读性。 单行注释:以#号开头,再加一个空格,后面跟上注释内容 TODO注释:# TODO 注释...

我是小谷粒
06/28
0
0
Peewee 3.2.5 发布,轻量级 Python ORM 库

Peewee 3.2.5 已发布,Peewee 是一个轻量级的 python ORM 库,内置对 SQLite、MySQL 和 PostgreSQL 的支持。支持 Python 2.7+ 和 Python 3.4+。 更新内容: 新增 ,示例如下: data = [(1, ...

王练
04/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

云拿 无人便利店

附近(上海市-航南路)开了家无人便利店.特意进去体验了一下.下面把自己看到的跟大家分享下. 经得现场工作人员同意后拍了几张照片.从外面看是这样.店门口的指导里强调:不要一次扫码多个人进入....

周翔
9分钟前
0
0
Java设计模式学习之工厂模式

在Java(或者叫做面向对象语言)的世界中,工厂模式被广泛应用于项目中,也许你并没有听说过,不过也许你已经在使用了。 简单来说,工厂模式的出现源于增加程序序的可扩展性,降低耦合度。之...

路小磊
22分钟前
0
0
npm profile 新功能介绍

转载地址 npm profile 新功能介绍 npm新版本新推来一个功能,npm profile,这个可以更改自己简介信息的命令,以后可以不用去登录网站来修改自己的简介了 具体的这个功能的支持大概是在6这个版...

durban
33分钟前
0
0
Serial2Ethernet Bi-redirection

Serial Tool Serial Tool is a utility for developing serial communications, custom protocols or device testing. You can set up bytes to send accordingly to your protocol and save......

zungyiu
39分钟前
0
0
python里求解物理学上的双弹簧质能系统

物理的模型如下: 在这个系统里有两个物体,它们的质量分别是m1和m2,被两个弹簧连接在一起,伸缩系统为k1和k2,左端固定。假定没有外力时,两个弹簧的长度为L1和L2。 由于两物体有重力,那么...

wangxuwei
54分钟前
0
0
apolloxlua 介绍

##项目介绍 apolloxlua 目前支持javascript到lua的翻译。可以在openresty和luajit里使用。这个工具分为两种模式, 一种是web模式,可以通过网页使用。另外一种是tool模式, 通常作为大规模翻...

钟元OSS
今天
0
0
Mybatis入门

简介: 定义:Mybatis是一个支持普通SQL查询、存储过程和高级映射的持久层框架。 途径:MyBatis通过XML文件或者注解的形式配置映射,实现数据库查询。 特性:动态SQL语句。 文件结构:Mybat...

霍淇滨
今天
0
0
开发技术瓶颈期,如何突破

前言 读书、学习的那些事情,以前我也陆续叨叨了不少,但总觉得 “学习方法” 就是一个永远在路上的话题。个人的能力、经验积累与习惯方法不尽相同,而且一篇文章甚至一本书都很难将学习方法...

_小迷糊
今天
0
0
安装tensorflow-XXX报错

报错: tensorflow-0.5.0-cp27-none-linux_x86_64.whl is not a supported wheel on this platform. 解决: wget https://bootstrap.pypa.io/get-pip.py sudo python2.7 get-pip.py sudo p......

Yao--靠自己
今天
0
0
JVM学习手册(一):JVM模型

一直从事JAVA开发,天天和JVM打交道,仔细想想对JVM还真的不是特别了解,实在是不应该.周六看了许多资料,也算有点心得,记录一下。 JVM内存模型分为5个区域:方法区,堆,虚拟机栈,本地方法栈,程序计...

勤奋的蚂蚁
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部