1. 程式人生 > 其它 >(轉)這有 73 個例子,徹底掌握 f-string 用法!

(轉)這有 73 個例子,徹底掌握 f-string 用法!

原文:https://jishuin.proginn.com/p/763bfbd32655

在本文中,我將向你展示我認為對 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='helloworld'>>>'msg:%s'%msg'msg:helloworld'

用string.format的樣例:

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

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

PEP 498 提出了一種新的字串插值方法,該方法可以更簡單便捷的使用 str.format 方法。你只需要在字串開頭加上一個字母 f,形成 f”” 的格式就可以了。

使用f-string的樣例:

>>>msg='helloworld'>>>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")
ThebookThedogguidehas124pages\n>>>print(FR"Thebook{book}has{num_pages}pages\n")ThebookThedogguidehas124pages\n>>>print(f"Thebook{book}has{num_pages}pages\n")ThebookThedogguidehas124pages

差不多就這些!下一節中,我會用一些例子向你展示一些你用f-string能做或不能做的事兒。

3、f-string 的限制

雖然f-string十分的便捷,但它並不能完全代替str.format。f-string在表示式出現的上下文中進行求值計算。根據PEP498,這意味著該表示式可以獲取所有區域性和全域性變數。而且該表示式是在執行時計算的表示式。如果在{}之中使用的表示式無法被計算,就會跳出如下異常。

>>>f"{name}"---------------------------------------------------------------------------NameErrorTraceback(mostrecentcalllast)<ipython-input-1in<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 "", line 1    f"My name is {name #name}!"    ^SyntaxError: f-string expression part cannot include '#'

4、如何格式化一個表示式

如果不想定義變數,那你可以在大括號中使用常量。Python會計算該表示式並顯示最終計算結果。

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

或者你可以...

>>>n=4
>>>f"4*4is{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}"'ARGBcolor'
#用`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-201c0ee8dd74be> in <module>----> 1 f'{c:j}'
<ipython-input-15985c4992e957> 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"numroundedto2decimalpalces={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、如何轉義符號

如果你想想列印由大括號括起來的變數名稱,而不是該變數的值,那你需要雙層大括號{{}}。

>>>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***'
#Extrapaddingisaddedtotheright>>>f"{hello:*^10}"'**world***'
#Nshorterthanlen(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(',','')'1234567890'

還有個方法是設定你的本地語言環境,換成一個用空格作千位分隔符的環境比如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="thisisb"
>>>f"{aif10>5elseb}"'thisisa'
>>>f"{aif10<5elseb}"'thisisb'

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-2320:24:17'

19、如何修復f-string的非法格式錯誤

如果用的不對,f-string會報格式錯誤。最常見的錯誤就是雙引號裡面套雙引號。單引號也會引發相同錯誤。

>>>color = {"R": 123, "G": 145, "B": 255}
>>>f"{color["R"]}" File"", line 1f"{color["R"]}"^SyntaxError:f-string:unmatched'['
>>>f'{color['R']}'File"",line1f'{color['R']}'^SyntaxError:f-string:unmatched'['

還有個常見錯誤是在舊版本python中用f-string。python3.6才引入了f-string。如果你在之前版本中使用這個方法,直譯器會報格式錯誤SyntaxError: invalid syntax。

>>> f"this is an old version"File"",line1f"thisisanoldversion"
SyntaxError:invalidsyntax

看到這個錯誤的話,先確定當前使用的python版本。我檢查的方法是在python2.7下通過呼叫sys.version來獲取版本號。

>>> import sys;print(sys.version)2.7.18(default,Apr202020,19:27:10)[GCC8.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...:...:^Iofcolor{color["R"]}   ...:    ...:'''
>>> other
'\nthis is an example\n\n\tof color 123\n \n'
>>>print(other)thisisanexampleofcolor123
>>>

22、結論

本文就這些!希望大家學到了一些新奇而實用的知識。知道了如何充分利用 f-string 絕對可以讓生活變得更美好。

技術連結