这有 73 个例子,彻底掌握 f-string 用法!

英文:Miguel Brito,翻译:Python开发者 /  felixGuo26

在本文中,我将向你展示我认为对 Python 格式化字符串 f-string 来说最重要的一些技巧。你会通过各种样例学到多种格式化字符串的方法。总的来说,就是你会看到73个关于如何完美应用 f-string 的例子。

目录一览

1. f-string 是什么?

2. 用 python 做基本的文本格式化

3. f-string 局限性

4. 如何格式化表达式

5. 如何使用f-string调试你的代码

6. 如何在不同进制下格式化数字

7. 如何使用格式化字符串常量打印出对象

8. 如何在格式化字符串常量中设置浮点数精度

9. 如何将数字格式化为百分比

10. 如何调整或者增加f-string的填充

11. 如何转义字符

12. 如何使字符串居中

13. 如何添加千位分隔符

13.1如何使用逗号作为千分位分隔符格式化数字

13.2如何使用逗号作为小数分隔符格式化数字

14.如何用科学计数法(指数计数法)格式化数字

15.在 f-string 中使用 if-else

16.如何在 f-string 中使用字典

17.如何用 f-string 拼接字符串

18.如何格式化 datetime 对象

19.如何改正 f-string 的无效语法错误

20.如何在字符串前补零

21.如何编写多行格式化字符串常量(怎样应对新行符号)

22.总结

1、python 中的 f-string 是什么?

在 Python 的历史中,字符串格式化的发展源远流长。在 python 2.6 之前,想要格式化一个字符串,你只能使用 % 这个占位符,或者string.Template 模块。不久之后,出现了更灵活更靠谱的字符串格式化方式: str.format 方法。

过去使用 % 做字符串格式化方式的代码样例:

    >>> msg = 'hello world'>>> 'msg: %s' % msg'msg: hello world'

    用string.format的样例:

      >>> msg = 'hello world'>>> 'msg: {}'.format(msg)'msg: hello world'

      为了进一步简化格式化方法,Eric Smith 在2015年提交了 PEP 498 -- Literal String Interpolation 提案。

      PEP 498 提出了一种新的字符串插值方法,该方法可以更简单便捷的使用 str.format 方法。你只需要在字符串开头加上一个字母 f,形成 f”” 的格式就可以了。

      使用f-string的样例:

        >>> msg = 'hello world'>>> f'msg: {msg}''msg: hello world'

        这就可以了!再也不需要用 string.format 或者 % 了。不过 f-string 并不能完全替代 str.format。本文也将列举出这两者并不通用的情况。

        2、基本的字符串格式化

        如上文所述,使用f-string格式化字符串十分简单。唯一的要求就是给它一个有效的表达式。f-string 也可以用大写F开头或者与 r 原始字符串结合使用。但是你不能将其与 b”” 或者 ”u” 混用。

          >>> book = 'The dog guide'>>> num_pages = 124>>> f'The book {book} has{num_pages} pages''The book The dog guide has 124 pages'>>> F'The book {book} has{num_pages} pages''The book The dog guide has 124 pages'>>> print(Fr'The book {book} has{num_pages} pages\n')The book The dog guide has 124 pages\n >>> print(FR'The book {book} has{num_pages} pages\n')The book The dog guide has 124 pages\n>>> print(f'The book {book} has{num_pages} pages\n')The book The dog guide has 124 pages

          差不多就这些!下一节中,我会用一些例子向你展示一些你用f-string能做或不能做的事儿。

          3、f-string 的限制

          虽然f-string十分的便捷,但它并不能完全代替str.format。f-string在表达式出现的上下文中进行求值计算。根据PEP498,这意味着该表达式可以获取所有局部和全局变量。而且该表达式是在运行时计算的表达式。如果在 { <expr> } 之中使用的表达式无法被计算,就会跳出如下异常。

            >>> f'{name}'---------------------------------------------------------------------------NameError                                 Traceback(most recent call last)<ipython-input-1-f0acc441190f> in<module>----> 1 f'{name}'NameError: name 'name' is not defined

            这对 str.format 来说就不是问题,你可以提前定义一个模板字符串,并在之后调用.format方法时再传递上下文信息。

              >>> s = '{name}'>>> s.format(name='Python')'Python'>>> print(s){name}

              另外还有个限制是,你不能在f-string中使用行内注释。

                >>> f'My name is {name #name}!' File '<ipython-input-37-0ae1738dd871>', line 1 f'My name is {name #name}!' ^SyntaxError: f-string expression part cannot include '#'

                4、如何格式化一个表达式

                如果不想定义变量,那你可以在大括号中使用常量。Python会计算该表达式并显示最终计算结果。

                  >>> f'4 * 4 is {4 * 4}''4 * 4 is 16'

                  或者你可以...

                    >>> n = 4
                    >>> f'4 * 4 is {n * n}''4 * 4 is 16'

                    5、如何使用 f-string 来调试代码

                    调试是f-string最常见的用途之一了。Python3.8 之前,很多人会用一种非常繁杂的hello = 42; f'hello = {hello}”来进行调试。针对此Python3.8引入了一个新功能。你可以用 f'{hello=}' 重写上面的代码,而python会显示hello=42。下面这个例子展示了在使用函数表达式时如何应用该特性,其原理与上文代码是一样的。

                      >>> def magic_number():     ...:     return 42     ...: >>> f'{magic_number() = }''magic_number() = 42'

                      6、如何格式化数字的不同进制

                      f-string 还能在不同进制下显示数字。例如,你不需要通过b来对一个int进行格式转化就可以显示其二进制结果。

                        >>> f'{7:b}''111'

                        总结一下就是你可以用f-string来格式化:

                        ·  int 到二进制

                        ·  int 到十六进制

                        ·  int 到八进制

                        ·  int 到十六进制(所有符号大写)

                        下面的例子使用缩进功能和进制格式化创建了一个表,可以显示数字在不同进制下的值。

                          >>> bases = {       'b': 'bin',        'o': 'oct',        'x': 'hex',        'X': 'HEX',        'd': 'decimal'}>>> for n in range(1, 21):     ...:     for base, desc in bases.items():     ...:         print(f'{n:5{base}}', end=' ')     ...:     print()    1     1     1     1     1    10     2     2     2     2    11     3     3     3     3   100     4     4     4     4   101     5     5     5     5   110     6     6     6     6   111     7     7     7     7  1000    10     8     8     8  1001    11     9     9     9  1010    12     a     A    10  1011    13     b     B    11  1100    14     c     C    12  1101    15     d     D    13  1110    16     e     E    14  1111    17     f     F    15 10000    20    10    10    16 10001    21    11    11    17 10010    22    12    12    18 10011    23    13    13    19 10100    24    14    14    20

                          7、如何用 f-string 打印对象

                          你可以用f-string打印自定义对象。默认设置是,如果你向f-string表达式传递了一个对象,它将会显示该对象 __str__ 方法的返回值。不过,你也可以用显式转换操作标志来打印__repr__的值。

                          • !r - 使用 repr() 将值转化为文本.

                          • !s - 使用 str() 将值转化为文本.

                            >>> class Color: def __init__(self, r: float = 255, g: float = 255, b: float = 255): self.r = r self.g = g self.b = b
                            def __str__(self) -> str: return 'A RGB color'
                            def __repr__(self) -> str: return f'Color(r={self.r}, g={self.g}, b={self.b})'
                            >>> c = Color(r=123, g=32, b=255)
                            # 如不加任何操作符, 会打印 __str__ 的值>>> f'{c}''A RGB color'
                            # 用`obj!r` 的话会打印 __repr__ 的值>>> f'{c!r}''Color(r=123, g=32, b=255)'
                            # 使用!s跟默认值一样>>> f'{c!s}''A RGB color'

                            Python也允许通过定义不同类型使用__format__方法控制格式化结果,下面的例子会展示所有可能情况。

                              >>> class Color:    def __init__(self, r: float = 255, g: float = 255, b: float = 255):        self.r = r        self.g = g        self.b = b    def __str__(self) -> str:        return 'A RGB color'    def __repr__(self) -> str:        return f'Color(r={self.r}, g={self.g}, b={self.b})'>>> c = Color(r=123, g=32, b=255)# When no option is passed, the __str__ result is printed>>> f'{c}''A RGB color'# When `obj!r` is used, the __repr__ output is printed>>> f'{c!r}''Color(r=123, g=32, b=255)'# Same as the default>>> f'{c!s}''A RGB color'Python also allows us to control the formatting on a per-type basis through the __format__ method. The following example shows how you can do all of that.>>> class Color:    def __init__(self, r: float = 255, g: float = 255, b: float = 255):        self.r = r        self.g = g        self.b = b    def __str__(self) -> str:        return 'A RGB color'    def __repr__(self) -> str:        return f'Color(r={self.r}, g={self.g}, b={self.b})'    def __format__(self, format_spec: str) -> str:        if not format_spec or format_spec == 's':            return str(self)        if format_spec == 'r':            return repr(self)        if format_spec == 'v':            return f'Color(r={self.r}, g={self.g}, b={self.b}) - A nice RGB thing.'        if format_spec == 'vv':            return (                f'Color(r={self.r}, g={self.g}, b={self.b}) '                f'- A more verbose nice RGB thing.'            )        if format_spec == 'vvv':            return (                f'Color(r={self.r}, g={self.g}, b={self.b}) '                f'- A SUPER verbose nice RGB thing.'            )        raise ValueError(            f'Unknown format code '{format_spec}' ' 'for object of type 'Color''        )>>> c = Color(r=123, g=32, b=255)>>> f'{c:v}''Color(r=123, g=32, b=255) - A nice RGB thing.'>>> f'{c:vv}''Color(r=123, g=32, b=255) - A more verbose nice RGB thing.'>>> f'{c:vvv}''Color(r=123, g=32, b=255) - A SUPER verbose nice RGB thing.'>>> f'{c}''A RGB color'>>> f'{c:s}''A RGB color'>>> f'{c:r}''Color(r=123, g=32, b=255)'>>> f'{c:j}'---------------------------------------------------------------------------ValueError                                Traceback (most recent call last)<ipython-input-20-1c0ee8dd74be> in <module>----> 1 f'{c:j}'<ipython-input-15-985c4992e957> in __format__(self, format_spec)     29                 f'- A SUPER verbose nice RGB thing.'     30             )---> 31         raise ValueError(     32             f'Unknown format code '{format_spec}' ' 'for object of type 'Color''     33         )ValueError: Unknown format code 'j' for object of type 'Color'

                              最后,还有个用来转义ASCII字符的a操作符。更多信息可参考:

                              docs.python.org/3/library/functions.html#as..

                                >>> utf_str = 'Áeiöu'
                                >>> f'{utf_str!a}'''\\xc1ei\\xf6u''

                                8、如何用f-string设定浮点数精度

                                F-string可以像str.format那样格式化浮点数。想要实现这一点,你需要加一个 :(冒号)再加一个 .(英文句号)然后跟着小数点位数最后以f结尾。

                                举例来说,你可以通过如下代码打印一个浮点数精确到百分位的近似值。

                                  >>> num =4.123956>>> f'num rounded to 2 decimalpalces = {num:.2f}''num rounded to 2 decimal palces = 4.12’

                                  不加任何选项的话,则会打印浮点数本身的精确值。

                                    >>> print(f'{num}')4.123956

                                    9、如何将一个数字格式化为百分数

                                    Python f-string方法有个非常便捷的实现格式化百分数的操作方法。方法与浮点数格式化类似,但是要用%代替结尾的f。它会将原始数值乘以100并显示成有百分符号的固定格式。精度一样也是可以设定的。

                                      >>> total = 87>>> true_pos = 34>>> perc = true_pos / total>>> perc0.39080459770114945>>> f'Percentage of true positive: {perc:%}''Percentage of true positive: 39.080460%'>>> f'Percentage of true positive: {perc:.2%}''Percentage of true positive: 39.08%'

                                      10、如何调整或者增加 f-string 的填充

                                      你可以便捷的通过 < 或者 > 符号来调整字符串填充。

                                        >>> greetings = 'hello'
                                        >>> f'She says {greetings:>10}''She says hello'
                                        # Pad 10 char to the right>>> f'{greetings:>10}'' hello'
                                        >>> f'{greetings:<10}''hello '
                                        # You can omit the < for left padding>>> f'{greetings:10}''hello '
                                          >>> a = '1'>>> b = '21'>>> c = '321'>>> d = '4321'>>> print('\n'.join((f'{a:>10}', f'{b:>10}', f'{c:>10}', f'{d:>10}')))         1        21       321      4321

                                          11、如何转义符号

                                          如果你想想打印由大括号括起来的变量名称,而不是该变量的值,那你需要双层大括号 {{<expr>}}。

                                            >>> hello = 'world'
                                            >>>f'{{hello}} = {hello}''{hello} = world'

                                            而如果你想转义双引号,就需要在引号前用反斜线 \ 做标记。

                                              >>>f'{hello} = \'hello\'''world = 'hello''

                                              12、如何使字符串居中

                                              想要实现字符串居中,可以通过 var:^N 的方式。其中var是你想要打印的变量,N是字符串长度。如果N小于var的长度,会打印全部字符串。

                                                >>> hello = 'world'>>>f'{hello:^11}'
                                                ' world '>>>f'{hello:*^11}''***world***'
                                                # Extra padding is added to the right>>>f'{hello:*^10}''**world***'
                                                # N shorter than len(hello)>>>f'{hello:^2}''world'

                                                13、如何格式化千分位

                                                F-string也允许我们自定义数字显示的格式。有个非常普遍的需求就是把数字以每3位为一个间隔使用下划线进行分隔。

                                                  >>> big_num = 1234567890>>> f'{big_num:_}''1_234_567_890'

                                                  13.1  如何使用逗号千分位分隔符数字

                                                  实际上,你可以随便用任何符号做千分位分隔符。所以用逗号做分隔符也完全没问题。

                                                    >>> big_num = 1234567890
                                                    >>> f'{big_num:,}''1,234,567,890'

                                                    甚至可以一次性同时搞定既有千分位分隔符又有精度设定的浮点数。

                                                      >>> num =2343552.6516251625>>> f'{num:,.3f}'‘2,343,552.652'

                                                      13.2 如何用空格做千分位分隔符

                                                      用空格也可以吗?

                                                      好吧,这个问题是挺棘手,不过也能实现。你可以用逗号做分隔符之后再用空格替换逗号。

                                                        >>> big_num = 1234567890
                                                        >>> f'{big_num:,}'.replace(',',' ')'1 234 567 890'

                                                        还有个方法是设定你的本地语言环境,换成一个用空格作千位分隔符的环境比如pl_PL(波兰语环境)。更多信息可参考这个Stack Overflow链接:

                                                        https://stackoverflow.com/a/17484665

                                                        14、如何用科学计数法(指数计数法)显示一个数字

                                                        可以用 e 或者 E 字符来格式化。

                                                          >>> num =2343552.6516251625>>>f'{num:e}''2.343553e+06'>>> f'{num:E}''2.343553E+06'>>> f'{num:.2e}''2.34e+06'>>> f'{num:.4E}''2.3436E+06'

                                                          15、在 f-string 中使用 if-else

                                                          F-string也能计算稍微复杂的运算式,比如if/else

                                                            >>> a = 'this is a'>>> b = 'this is b'
                                                            >>> f'{a if 10 > 5 else b}''this is a'
                                                            >>> f'{a if 10 < 5 else b}''this is b'

                                                            16、如何在 f-string 中使用字典

                                                            你可以在f-string中使用字典。唯一的要求是引起整个字符串的引号要跟内部的引号不一样。

                                                              >>>color = {'R': 123, 'G': 145, 'B': 255}>>> f'{color['R']}''123'>>> f'{color['R']}'‘’123'此处有误啊应该是‘123’吧>>> f'RGB = ({color['R']},{color['G']}, {color['B']})''RGB = (123, 145, 255)’

                                                              17、如何用 f-string 拼接字符串

                                                              合并f-string与普通字符串拼接一样,可以隐式的直接拼接,或者显式地用加号 +,或者使用 str.join 方法。

                                                                # 隐式字符串拼接>>> f'{123}' ' = 'f'{100}' ' + ' f'{20}' ' + 'f'{3}''123 = 100 + 20 + 3'
                                                                # 使用加号 + 的显式字符串拼接>>> f'{12}' + ' != '+ f'{13}''12 != 13'
                                                                # 使用str.join的字符串拼接>>> ''.join((f'{13}', f'{45}'))'13 45'
                                                                >>>'#'.join((f'{13}', f'{45}'))'13#45'

                                                                18、如何格式化 datetime 对象

                                                                F-string也支持datetime对象的格式化。其过程与str.format格式化日期的方法很近似。请查阅官方文档中的表格获取更多所支持格式的相关信息。

                                                                  >>> import datetime>>> now = datetime.datetime.now()>>> ten_days_ago = now -datetime.timedelta(days=10)>>> f'{ten_days_ago:%Y-%m-%d %H:%M:%S}''2020-10-13 20:24:17'>>> f'{now:%Y-%m-%d %H:%M:%S}''2020-10-23 20:24:17'

                                                                  19、如何修复f-string的非法格式错误

                                                                  如果用的不对,f-string会报格式错误。最常见的错误就是双引号里面套双引号。单引号也会引发相同错误。

                                                                    >>>color = {'R': 123, 'G': 145, 'B': 255}
                                                                    >>> f'{color['R']}' File'<ipython-input-43-1a7f5d512400>', line 1   f'{color['R']}'   ^SyntaxError: f-string: unmatched '['
                                                                    >>> f'{color['R']}'  File'<ipython-input-44-3499a4e3120c>', line 1   f'{color['R']}'   ^SyntaxError: f-string: unmatched '['

                                                                    还有个常见错误是在旧版本python中用f-string。python3.6才引入了f-string。如果你在之前版本中使用这个方法,解释器会报格式错误 SyntaxError: invalid syntax。

                                                                      >>> f'this is an old version' File'<stdin>', line 1   f'this is an old version'SyntaxError: invalid syntax

                                                                      看到这个错误的话,先确定当前使用的python版本。我检查的方法是在python2.7下通过调用sys.version来获取版本号。

                                                                        >>> import sys;print(sys.version)2.7.18 (default, Apr 202020, 19:27:10)[GCC 8.3.0]

                                                                        20、如何在字符串前补零

                                                                        可以用{expr:0len} 这个方法来进行字符串补零。len是最终返回字符串的长度。还可以增加一个正负号标记。在这种情况下,用+则无论数值为正负数都将显示相应正负号。用-则只有当数值为负数时才显示负号,默认设定也是如此。更多信息可参考该链接

                                                                        https://docs.python.org/3/library/string.html#format-specification-mini-language

                                                                          >>> num = 42>>> f'{num:05}''00042'>>> f'{num:+010}''+000000042'>>> f'{num:-010}''0000000042'>>> f'{num:010}''0000000042'>>> num = -42>>> f'{num:+010}''-000000042'>>> f'{num:010}''-000000042'>>> f'{num:-010}''-000000042'

                                                                          21、如何处理多行f-string(换行符的处理)

                                                                          你可以用换行符\n来打印多行文本。

                                                                            >>> multi_line = (f'R: {color['R']}\nG: {color['G']}\nB: {color['B' ...: ]}\n')
                                                                            >>> multi_line'R: 123\nG: 145\nB: 255\n'
                                                                            >>> print(multi_line)R: 123G: 145B: 255

                                                                            还可以用三引号实现多行字符串。这样不单能增加换行符,还能有Tab。

                                                                              >>> other = f'''R:{color['R']}    ...: G:{color['G']}    ...: B:{color['B']}    ...:'''>>> print(other)R: 123G: 145B: 255

                                                                              用 Tab 的代码样例

                                                                                >>> other = f''' ...:this is an example    ...:    ...:^Iof color {color['R']} ...:     ...: '''
                                                                                >>> other
                                                                                '\nthis is an example\n\n\tof color 123\n \n'
                                                                                >>> print(other)this is an example    of color123
                                                                                >>>

                                                                                22、结论

                                                                                本文就这些!希望大家学到了一些新奇而实用的知识。知道了如何充分利用 f-string 绝对可以让生活变得更美好。

                                                                                (0)

                                                                                相关推荐

                                                                                • Python魔法方法漫游指南:类的表示

                                                                                  使用字符串等信息来表示类是一个相当实用的特性.比方说你在调试代码时,会频繁使用 print() 等函数来获取对象信息,其背后就是隐式调用了将类转化为字符串的魔法方法.相对应的,还有另一部分魔法方法用于 ...

                                                                                • TypeScript---数据类型

                                                                                  TypeScript---数据类型 //字符串 let str: string = "你好ts" let str1: string = "你好typescript&quo ...

                                                                                • Python基础学习笔记(一)变量与数据类型

                                                                                  https://m.toutiao.com/is/J3fN6eK/ Python是一门易学的面向对象的程序设计语言,可以轻易地完成界面.文件.封装等高阶需求,可移植性好,有非常多功能强大的库与包,如N ...

                                                                                • CAD中,掌握这Shi6个f键用法,让你画图效率飞升!

                                                                                  Shift键又叫做上档转换键,除了我们经常使用的输入法切换.快速切换等功能之外,还可以与鼠标以及键盘其他键位组合使用,如选择连续文件(与鼠标首尾点配合).直接删除文件(与Delete组合使用)等. 在 ...

                                                                                • F# 函数式编程之 - 一个例子

                                                                                  经过本系列前面几篇文章对 F# 的介绍,是时候来一个比较小巧的例子了. 这个例子的原文见 https://fsharpforfunandprofit.com/posts/roman-numerals/ ...

                                                                                • 搭载18架美英F

                                                                                  美海军陆战队F-35B隐身短垂战机5月2日停泊在英国"伊丽莎白女王"号航母上.(美国海军陆战队网站) 参考消息网5月7日报道 美国军事网站5月2日发表题为<英国航母搭载着美国 ...

                                                                                • 老年人73岁是道“寿命坎”,坚持做好5事,成功跨过

                                                                                  中国民间有一种普遍存在的现象:"七十三八十四,阎王不请自己去",就是说老人们到了73岁和84岁的时候,就像是要经过生命中的一个坎,跨过了皆大欢喜,跨不过就止步在这里了,确确实实很多 ...

                                                                                • 运维必知必备!73页计算机基础知识,新手小白也能轻松读懂

                                                                                  基础不牢,地动山摇! 新手在学习运维亦或是开发的时候,都要注重基础知识的积累,不能只想着学习实战知识,这样到中后期,容易造成对"高级知识点"的一知半解,以至于知其然,却不知其所以然 ...

                                                                                • 小学谐音歇后语73句

                                                                                  小学谐音歇后语73句

                                                                                • 隐形冠军是F

                                                                                  隐形冠军是F-117颇令人意外,在一般人的印象里,它速度慢.机动性差,连雷达都没有,还很不光彩的被击落了一架,成为对手脚下的战利品,但这些都是它追求极致隐身付出的代价. B-2之所以能在翼展达52.4 ...

                                                                                • 套内仅73㎡,全屋堪称“教科书式”装修,日子过得清爽又干净

                                                                                  设计源于生活,好的装修一定是融合了生活习惯.有设计有生活,那种居家场面看着就很养眼.这期分享的案例就是如此,套内仅73㎡,依托巧妙的布局设计和生活习惯的结合,全屋堪称"教科书式"装 ...

                                                                                • 李本深《灵魂的重量》73、74章

                                                                                  73.人生如梦 天广地阔, 问乾坤何处能容我 荆棘载途. 无路不险恶 此是樊笼, 彼是囚笼, 人间本是大监狱 莫道人生如梦, 只缘世事朦胧 上九天问津 哪来琼楼玉宇, 下四海求索 惟有砧俎鼎镬, 不须 ...