python3中format方法_[翻译]python3中新的字符串格式化方法-----f-string

从python3.6开始,引入了新的字符串格式化方式,f-字符串. 这使得格式化字符串变得可读性更高,更简洁,更不容易出现错误而且速度也更快.

在本文后面,会详细介绍f-字符串的用法. 在此之前,让我们先来复习一下python中字符串格式化的方法.

python中传统的字符串格式化方法.

在python3.6之前,我们有两种方式可以用来格式化字符串.

占位符+%的方式

str.format()方法

首先复习一下这两种方式的使用方法以及其短板.

占位符+%的方式

这种方式算是第0代字符串格式化的方法,很多语言都支持类似的字符串格式化方法. 在python的文档中,我们也经常看到这种方式.

但是!!!

BUT!!!

占位符+%的方式并不是python推荐的方式.

Note 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, the str.format() interface, or template strings may help avoid these errors. Each of these alternatives provides their own trade-offs and benefits of simplicity, flexibility, and/or extensibility.(Python3 doc)

文档中也说了,这种方式对于元组等的显示支持的不够好. 而且很容易产生错误.

而且不符合python代码简洁优雅的人设...

「如何使用占位符+%的方式」

如果你接触过其他的语言,这种方式使用起来会有一种诡异的亲切感,这种亲切感会让你抓狂,内心会暗暗的骂上一句,艹,又是这德行...(这句不是翻译,是我的个人感觉,从来都记不住那么多数据类型的关键字...)

In [1]: name='Eric'

In [2]: 'Hello,%s'%name

Out[2]: 'Hello,Eric'

如果要插入多个变量的话,就必须使用元组.像这样

In [3]: name='Eric'

In [4]: age=18

In [5]: 'Hello %s,you are %d.'%(name,age)

Out[5]: 'Hello Eric,you are 18.'

「为什么说占位符+%的方式不是最好的办法(个人认为是这种方式是一种最操蛋的操作)」

上面有少量的变量需要插入到字符串的时候,这种办法还行. 但是一旦有很多变量需要插入到一个长字符串中...比如...

In [6]: first_name = "Eric"

...: last_name = "Idle"

...: age = 74

...: profession = "comedian"

...: affiliation = "Monty Python"

In [7]: "Hello, %s %s. You are %s. You are a %s. You were a member of %s." % (first_name, last_name, age, profession, affiliation)

Out[7]: 'Hello, Eric Idle. You are 74. You are a comedian. You were a member of Monty Python.'

像上面这个例子,代码可读性就很差了.(对读和写的人都是一种折磨...)

使用str.format()的方式

在python2.6之后,引入了str.format()函数,可以用来进行字符串的格式化. 它通过调用对象的__format__()方法(PEP3101中定义)来将对象转化成字符串.

在str.format()方法中,通过花括号占位的方式来实现变量插入.

In [8]: 'hello,{}. You are {}.'.format(name,age)

Out[8]: 'hello,Eric. You are 74.'

甚至可以给占位符加索引.

In [9]: 'hello,{1}. You are {0}.'.format(age,name)

Out[9]: 'hello,Eric. You are 74.'

如果要在占位符中使用变量名的话,可以像下面这样

In [10]: person={'name':'Eric','age':74}

In [11]: 'hello,{name}. you are {age}'.format(name=person['name'],age=person['age'])

Out[11]: 'hello,Eric. you are 74'

当然对于字典来说的话,我们可以使用**的小技巧.

In [15]: 'hello,{name}. you are {age}'.format(**person)

Out[15]: 'hello,Eric. you are 74'

str.format()方法对于%的方式来说已经是一种很大的提升了. 但是这并不是最好的方式.

「为什么format()方法不是最好的方式」

相比使用占位符+%的方式,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}.") \

>>> .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.'

当然,我们也可以通过字典的方式直接传入一个字典来解决代码过长的问题. 但是,python3.6给我们提供了更便利的方式.

f-字符串,一种新的增强型字符串格式化方式

这种新的方式在PEP498中定义.(原文写到这里的时候,作者可能疯了,balabla说了一长串,冷静的我并没有翻译这些废话...)

这种方式也被叫做formatted string literals.格式化的字符串常亮...ummm...应该是这么翻译吧...

这种方式在字符串开头的时候,以f标识,然后通过占位符{}+变量名的方式来自动解析对象的__format__方法. 如果想了解的更加详细,可以参考python文档

一些简单的例子

「使用变量名作为占位符」

In [16]: name = 'Eric'

In [17]: age=74

In [18]: f'hello {name}, you are {age}'

Out[18]: 'hello Eric, you are 74'

「这里甚至可以使用大写的F」

In [19]: F'hello {name}, you are {age}'

Out[19]: 'hello Eric, you are 74'

你以为这就完了吗?

不!

事情远不止想象的那么简单...

在花括号里甚至可以执行算数表达式

In [20]: f'{2*37}'

Out[20]: '74'

如果数学表达式都可以的话,那么在里面执行一个函数应该不算太过分吧...

In [22]: def to_lowercase(input):

...: return input.lower()

...:

In [23]: name = 'ERIC IDLE'

In [24]: f'{to_lowercase(name)} is funny'

Out[24]: 'eric idle is funny'

你以为这就完了吗?

不!

事情远不止想象的那么简单...

这玩意儿甚至可以用于重写__str__()和__repr__()方法.

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__()方法. 这是对象的两个内置方法.__str()__方法用于返回一个便于人类阅读的字符串. 而__repr__()方法返回的是一个对象的准确释义. 这里暂时不做过多介绍. 如有必要,请关注公众号吾码2016(公众号:wmcoding)并发送str_And_repr

默认情况下,f-关键字会调用对象的__str__()方法. 如果我们想调用对象的__repr__()方法的话,可以使用!r

>>>f"{new_comedian}"

'Eric Idle is 74.'

>>>f"{new_comedian!r}"

'Eric Idle is 74. Surprise!'

更多详细内容可以参考这里

多个f-字符串占位符

同样的,我们可以使用多个f-字符串占位符.

>>>name = "Eric"

>>>profession = "comedian"

>>>affiliation = "Monty Python"

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

同样的,在字符串换行的时候,每一行也要写上f.

>>>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.'

但是如果我们使用"""的时候,不需要每一行都写.

>>>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可能代表的含义是fast,因为f-字符串的速度比占位符+%的方式和format()函数的方式都要快.因为它是在运行时计算的表达式而不是常量值.(那为啥就快了呢...不太懂啊...)

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

(官方文档,咱不敢翻,大意就是f-字符串是一个在运行时参与计算的表达式,而不是像常规字符串那样是一个常量值)

在运行时,花括号内的表达式在其自己的作用域内求职,单号和字符串的部分拼接到一起,然后返回.

下面我们来看一个速度的对比.

import timeit

time1 = timeit.timeit("""name = 'Eric'\nage =74\n'%s is %s'%(name,age)""",number=100000)

time2 = timeit.timeit("""name = 'Eric'\nage =74\n'{} is {}'.format(name,age)""",number=100000)

time3 = timeit.timeit("""name = 'Eric'\nage =74\nf'{name} is {age}'""",number=100000)

从结果上看的话,f-字符串的方式速度要比其他两种快.

0.030868000000000007

0.03721939999999996

0.0173276

f-字符串的一些细节问题

「引号的问题」

在f-字符串中,注意成对的引号使用.

f"{'Eric Idle'}"

f'{"Eric Idle"}'

f"""Eric Idle"""

f'''Eric Idle'''

以上这几种引号方式都是支持的. 如果说我们在双引号中需要再次使用双引号的时候,就需要进行转义了.

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

「字典的注意事项」

在字典使用的时候,还是要注意逗号的问题.

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

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

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

比如上面两条语句,第三句就是有问题的,主要还是引号引起的歧义.

「花括号」

如果字符串中想使用花括号的话,就要写两个花括号来进行转义. 同理,如果想输出两个花括号的话,就要写四个...

>>>f"{{74}}"'{74}'

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

「反斜杠」

反斜杠可以用于转义. 但是!!!BUT!!!在f-字符串中,不允许使用反斜杠.

>>>f"{\"Eric Idle\"}"

File "", line 1

f"{\"Eric Idle\"}"

^SyntaxError: f-string expression part cannot include a backslash

像上面这个的解决办法就是

>>>name = "Eric Idle"

>>>f"{name}"'Eric Idle'

「行内注释」

f-字符串表达式中不允许使用#符号.

总结和参考资料

我们依旧可以使用老的方式进行字符串格式化输出. 但是通过f-字符串,我们现在有了一种更便捷,更快,可读性更高的方式. 根据python教义,Zen of Python:

「there should be one– and preferably only one –obvious way to do it.」

(编程还编出哲理来了...实在不会翻,有一种醍醐灌顶的感觉,内心浮现一个声音,卧槽!好有道理,仿佛自己升华了,但是仔细想想...这句话到底啥意思呢...)

更多的参考资料(我也只是写在这里,反正我是没有闲心看它的...):

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/394646.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为mate40会不会有鸿蒙系统,鸿蒙OS系统正式推送,拿华为Mate40更新后,发现了优缺点...

自从鸿蒙系统正式推送之后,笔者一直都带着好奇心在体验着HarmonyOS 2带来的变化,生怕错过惊喜,也担心系统本身会出现不足。因为鸿蒙系统就像是年轻人一样,才刚刚出炉,需要时间去磨练,然后才能发挥出真正强大…

jstack使用

jstack主要用来查看某个Java进程内的线程堆栈信息,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多,语法格式如下: jstack [option] pid jstack [option] executable core jstack [option] [server-id]rem…

如何使用TensorFlow对象检测API播放Quidditch

by Bharath Raj巴拉斯拉吉(Bharath Raj) 如何使用TensorFlow对象检测API播放Quidditch (How to play Quidditch using the TensorFlow Object Detection API) Deep Learning never ceases to amaze me. It has had a profound impact on several domains, beating benchmarks …

删除目录软链接注意事项

2019独角兽企业重金招聘Python工程师标准>>> 实验环境: 在root 目录下创建一个目录 1 ,并在该目录下创建一个2.txt 的文件,写入内容 1.txt: [rootserver ~]# mkdir 1 [rootserver ~]# echo 1.txt > 1/2.txt [rootserver ~]# tree 1 1 └─…

html如何模拟点击,Javascript 模拟点击事件(点击链接与html点击) 兼容IE/Firefox

一把情况下模拟点击一般两个方面,模拟点击超级连接事件firefox的兼容的函数为对HTMLAnchorElement 加入onclick事件try {// create a element so that HTMLAnchorElement is accessibledocument.createElement(a);HTMLElement.prototype.click function () {if (ty…

mvn编写主代码与测试代码

maven编写主代码与测试代码 3.2 编写主代码 项目主代码和测试代码不同,项目的主代码会被打包到最终的构件中(比如jar),而测试代码只在运行测试时用到,不会被打包。默认情况下,Maven假设项目主代码位于src/…

打印速度快点的打印机_SLM推出了功能强大的新型金属3D打印机,速度快20倍

德国金属3D打印机制造商SLM Solutions在Formnext Connect贸易展览会上推出了功能强大的新系统NXG XII 600。SLM的大幅面机器配备了十二个可同时运行的1 KW激光器,使其速度比该公司自己的单激光SLM 280快20倍。NXG XII 600经过定制设计,可大量生产大型零件…

把转变为json_如何使用7行JSON将您的网站转变为移动应用程序

把转变为jsonby Ethan通过伊桑 将Web引擎融合到本机应用程序的新方法 (A New Approach for Blending Web Engine into Native Apps) What if I told you the 7 lines of JSON above, colored in orange is all you need to turn a website into a mobile app? No need to rew…

1.7Oob 继承关系中构造方法的使用

1:父类中最好要有一个空参数的构造方法,因为默认的构造方法在自定义了构造方法后就不存在了,需要显示的写出来。 若父类中没有空参数的构造方法,则子类必须有自定义的构造方法,且用super()调用父…

JavaScript浮点运算0.2+0.1 !== 0.3

浮点运算JavaScript 本文主要讨论JavaScript的浮点运算,主要包括 JavaScript number基本类型二进制表示十进制浮点数的精度number 数字类型 在JavaScript中,数字只有number这一种类型; var intS 2,floatA 0.1; typeof intS; // number typeof floatA…

html获取data-*值,html5 获取和设置data-*属性值的四种方法讲解

1、获取id的对象2、需要获取的就是data-id 和 dtat-vice-id的值一:getAttribute()方法const getId document.getElementById(getId);// //getAttribute()取值属性console.log(getId.getAttribute("data-id"));//console.log(getId.getAttribute("da…

三菱模拟量输入与输出程序_初学PLC是学习西门子还是三菱?

PLC的种类繁多,品牌大多分为欧系、日系、美系。德系PLC以西门子为主,日系有三菱、欧姆龙、松下……,美系有罗克韦尔(A-B)通用电气(GE)公司、莫迪(MODICON)公司等。美国和欧洲的PLC技术是在相互隔离情况下独立研究开发的,因此美国和…

性能测试十四:Xshell链接linux虚拟机

一、先装一个linux虚拟机 VBoxcentos1、先下载Linux镜像文件的ovf或者OVA文件2、打开vbox,点击菜单栏“管理”-“导入虚拟电脑3、选择解压路径中的ovf或者OVA文件,点击下一步 4、点击“导入”,等待完成5、导入成功后,选择新导入的…

代码编写工具_我希望在开始编写代码时就已经知道的工具:已复习

代码编写工具by Mario Hoyos通过马里奥霍约斯(Mario Hoyos) 我希望在开始编写代码时就已经知道的工具:已复习 (Tools I wish I had known about when I started coding: Revisited) A few days ago, I wrote this article for freeCodeCamp which has since gone o…

Hydra扫描姿势

参数详解: -R 根据上一次进度继续破解 -S 使用SSL协议连接 -s 指定端口 -l 指定用户名 -L 指定用户名字典(文件) -p 指定密码破解 -P 指定密码字典(文件) -e 空密码探测和指定用户密码探测(ns) -C 用户名可以用:分割(username:password)可以代替-l username -p pass…

html5进度条插件 传递参数,Html5进度条插件(自写)

(function () {window.H5ProgressBar function (obj) {this.height obj.height;this.width obj.width;this.speed obj.speed;};//在界面上布局元素H5ProgressBar.prototype.drawLayout function () {document.write("开始下载")document.write(" ")do…

python合并txt文本_Python实现将目录中TXT合并成一个大TXT文件的方法

本文实例讲述了Python实现将目录中TXT合并成一个大TXT文件的方法。分享给大家供大家参考。具体如下: 在网上下了一个dota的英雄攻略,TXT格式,每个英雄一个文件,看得疼,就写了一个小东西,合并一下. #codinggbk import os import sys import glob def dirTxtToLargeTx…

读取字符串中的数字和小数

package com.jm.label.tools;import java.util.Map;import java.util.TreeMap;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * 读取字符串中的数字和小数 * author JM.H * */public class DigitUtil { public static String getNumber(String str){ …

html网页设计要点,网站交互设计的8个要点

一、力求一致性例如网站首页需要和每一个下级页面保持一致的风格,导航都要放在屏幕的左上角,具有高度一致性的界面能给人清晰整洁的感觉。二、允许频繁使用快捷键快捷键表示产品使用的灵活性和有效性,想想每次我们使用搜索引擎的时候是鼠标点…

行为扩展以及插件机制

在thinkPHP中的行为扩展和插件机制。 首先行为扩展这个概念是TP框架的核心组成之一,关于行为的解释我就粗略的概括一下吧: TP在从接受到HTTP请求到最终将试图输出,期间经历的很多步骤,这些步骤大家可以在http://document.thinkphp…