[Python 3.6] 初探格式化字串實字 (Formatted string literals)

Formatted string literals,我暫時翻譯成格式化字串實字,是 Python 在 3.6版加入的新特色,這個功能源自於 PEP 中的 498號提案,而這個特色又被稱作 f-string,讓我們來看看要怎麼使用吧:
name = 'Sky'
print(f'My name is {name}.')
# 'My name is Sky.'
有看到單引號前的 f 嗎?那是表示這個字串中會包含需要被取代的部分(F 也可以),然後讓我們看看字串中間的左大括號,這是取代欄位的開始,右大括號則是標示出了這個欄位的結束。

  • Replacement field  取代欄位
在這個欄位中,基本上可以放入任何 Python表示式,甚至包含 lambda 函式:
myNumber = 5
print(f'''My number is a 
{(lambda n: "Lucky" if n % 3 == 0 else "Unlucky")(myNumber)} number.''')
# My number is a 
# Unlucky number.
需要注意的是:lambda 主體需要以 ( ) 小括號包住,否則會引起 SyntaxError 例外;這裡同時展現了 f-string 另一個特色:可以像我們平常使用字串時那樣以三個引號表達多行字串,同樣地,任何空白字元都會被包起來,成為字串的一部分。

  • 小問題
如果你寫了一行這樣的程式碼:
print(f'"{" is a opening curly bracket.')
#   File "<stdin>", line 1
# SyntaxError: f-string: unterminated string
會發現說引起了 SyntaxError 例外,為什麼呢?
應該很淺顯易懂,左大括號代表的是一個欄位的起點,所以上述的例子中,Python直譯器會找不到代表結束的右大括號。

那如果字串中需要一個真正的左 / 右大括號呢?  可以使用{{ 或 }},將兩個大括號連在一起:
print(f'"{{" is a opening curly bracket.')
# "{" is a opening curly bracket.


  • Conversion field  轉換欄位
轉換欄位以 ! 作為開始:
import datetime
print(f'The time now is {datetime.datetime.now()}.')
# The time now is 2017-01-24 22:48:13.117520.
print(f'The time now is {datetime.datetime.now()!r}.')
# The time now is datetime.datetime(2017, 1, 24, 22, 48, 19, 414828).
換欄位的位置在於取代欄位中,要被轉換的表示式(變數)後面,共有 !a、!r、!s 三種轉換欄位。
  1. !a 代表對整個取代結果使用 ascii() 函式
  2. !r 則是 repr()
  3. !s 當然就是 str() 啦

  • 巢狀欄位
其實正式上來說也不算是巢狀欄位啦,就像 string.format() 方法一樣,你可以指定取代後的格式,例如說:
from decimal import Decimal
value = Decimal('89.65432')
allWidth = 10
precision = 3
print(f'value:{value:{allWidth}.{precision}}')
# value:      89.7
如果是浮點數的話他會幫你四捨五入
 
  • 小問題-2
在取代欄位中,不能有反斜線(\),就算用 r 包起來也一樣
print(f"newline: {ord('\n')}")
# SyntaxError: f-string expression part cannot include a backslash

newline = ord('\n')
print(f"newline: {newline}")
# newline: 10

留言

  1. 您好,请问如何使用f-string 如何传入**kwargs参数呢?

    回覆刪除
    回覆
    1. 你好,請問是否可以再更詳細地描述你的問題呢?我不太確定你說的情形是怎麼樣的。

      如果是把 f-string 當成參數的話是要用一般的方法就好了,像 foo( arg1=f"hello, {name}" ),前提是要已經有name這個變數。

      還是是其它的情形呢?

      刪除

  2. >>> person = {'name': 'Eric', 'age': 74}
    >>>"Hello, {name}. You are {age}.".format(**person)
    输出(plain):
    >>>'Hello, Eric. You are 74.'

    我的问题是 f-string 如何像上面demo里面的str.format 加** 双星号这个参数呢?如果存在,希望展示一段code demo.谢谢博主的回复.

    回覆刪除
    回覆
    1. 沒有你說的那種方法,不過要達到一樣效果可以這麼用:f'Hello, {person["name"]}'
      注意 person 裡的 name 要加上雙引號""。

      但是這樣好像很麻煩,所以還是乖乖的用str.format好了。

      刪除
    2. 參考資料:https://stackoverflow.com/questions/43488137/how-to-do-a-dictionary-format-with-f-string-in-python-3-6

      刪除

張貼留言

這個網誌中的熱門文章

[C] 每天來點字串用法 (2) - strcpy()、strncpy()

[Python] *args 和 **kwargs 是什麼?一次搞懂它們!

[C] 每天來點字串用法 (5) - strcat()、strncat()