python f-string




文章目錄
  1. 1. 主要內容
    1. 1.1. 舊時代的格式化字符串
      1. 1.1.1. Option #1: %-formatting
      2. 1.1.2. 怎樣使用 %-formatting
      3. 1.1.3. 為什么 %-formatting不好用
    2. 1.2. Option #2: str.format()
      1. 1.2.1. 怎樣使用Use str.format()
      2. 1.2.2. 為什么 str.format() 並不好
    3. 1.3. f-Strings:一種改進Python格式字符串的新方法
      1. 1.3.1. 簡單例子
      2. 1.3.2. 任意表達式
      3. 1.3.3. 多行f-string
      4. 1.3.4. 性能
    4. 1.4. Python f-Strings:Pesky細節
      1. 1.4.1. 引號
      2. 1.4.2. 字典
    5. 1.5. 大括號
      1. 1.5.1. 反斜杠
      2. 1.5.2. lambda表達式
    6. 1.6. 結束語
    <!-- Gallery -->


    <!-- Post Content -->
    <p><span></span><br><a id="more"></a></p>

主要內容

從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." %</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.'

不幸的是,這種格式不是很好,因為它是冗長的,會導致錯誤,比如不能正確顯示元組或字典。幸運的是,未來有更光明的日子。

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}.") </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開始加入標准庫。您可以在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<span class="string">" 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 "&lt;ipython-input-40-cd7d8a3db23b&gt;", 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"{<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使用,這可能會導致一些問題:

        
        
        
                
1
        
        
        
                
f"{lambda x: x * 37 (2)}"
  File "&lt;fstring&gt;", 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字符串不是唯一可能的方式為了格式化字符串,他們很有可能成為完成工作的一種明顯方式。

</div></div>
posted @ 2018-07-19 08:41  公眾號python學習開發  閱讀( 13215)  評論( 0編輯  收藏


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM