Python 3.6 提供了一種新的字符串格式化方法:f-strings
,不只比其餘格式化方式更易讀,更簡潔,更不容易出錯,並且它們也更快!html
看完本文後,你將瞭解如何以及爲什麼要使用 f-strings。python
首先,咱們先了解下現有的字符串格式化方法。express
在 Python 3.6 以前,字符串格式化方法主要有兩種:%格式化
和 str.format()
。下面咱們簡單看下它們的使用方法,以及侷限。微信
% 格式化方法從 Python 剛開始時就存在了,堪稱「一屆元老」,可是 Python 官方文檔中並不推薦這種格式化方式:less
這裏描述的格式化操做容易表現出各類問題,致使許多常見錯誤(例如沒法正確顯示元組和字典)。
使用較新的格式化字符串文字或 str.format() 能夠有助於避免這些錯誤。這些替代方案還提供了更強大,靈活和可擴展的格式化文本方法。
通常使用方式,要插入多個變量的話,必須使用元組:ide
>>> name = "hoxis" >>> age = 18 >>> "hello, %s. you are %s ?" %(name, age) 'hello, hoxis. you are 18 ?'
上面的代碼示例看起來還能讀,可是,一旦開始使用多個參數和更長的字符串,你的代碼將很快變得不那麼容易閱讀:函數
>>> name = "hoxis" >>> age = 18 >>> country = "China" >>> hair = "black" >>> "hello, %s. you are %s ?. Your country is %s, and your hair is %s" %(name, age, country,hair) 'hello, hoxis. you are 18 ?. Your country is China, and your hair is black'
能夠看出,這種格式化並非很好,由於它很冗長而且容易致使錯誤,好比沒有正確顯示元組或字典。ui
不過還好咱們還有 str.format()。this
Python 2.6 中引入了 str.format() 格式化方法:https://docs.python.org/3/lib...。idea
str.format() 是對 %格式化
的改進,它使用普通函數調用語法,而且能夠經過 __format__()
方法爲對象進行擴展。
使用 str.format() 時,替換字段用大括號進行標記:
>>> "hello, {}. you are {}?".format(name,age) 'hello, hoxis. you are 18?'
而且能夠經過索引來以其餘順序引用變量:
>>> "hello, {1}. you are {0}?".format(age,name) 'hello, hoxis. you are 18?'
或者能夠這樣:
>>> "hello, {name}. you are {age1}?".format(age1=age,name=name) 'hello, hoxis. you are 18?'
從字典中讀取數據時還可使用 **
:
>>> person = {"name":"hoxis","age":18} >>> "hello, {name}. you are {age}?".format(**person) 'hello, hoxis. you are 18?'
確實,str.format() 比 %格式化高級了一些,可是它仍是有本身的缺陷。
在處理多個參數和更長的字符串時仍然可能很是冗長,麻煩!看看這個:
>>> "hello, {}. you are {} ?. Your country is {}, and your hair is {}".format(name, age, country,hair) 'hello, hoxis. you are 18 ?. Your country is China, and your hair is black'
還好,如今咱們有了 f-Strings,它可使得字符串格式化更加容易。
f-strings 是指以 f
或 F
開頭的字符串,其中以 {}
包含的表達式會進行值替換。
下面從多個方面看下 f-strings 的使用方法,看完後,我相信你會對「人生苦短,我用 Python」有更深地贊同~
>>> name = 'hoxis' >>> age = 18 >>> f"hi, {name}, are you {age}" 'hi, hoxis, are you 18' >>> F"hi, {name}, are you {age}" 'hi, hoxis, are you 18'
是否是很簡潔?!還有更牛叉的!
由於 f-strings 是在運行時計算的,那麼這就意味着你能夠在其中放置任意合法的 Python 表達式,好比:
>>> f"{ 2 * 3 + 1}" '7'
還能夠調用函數:
>>> def test(input): ... return input.lower() ... >>> name = "Hoxis" >>> f"{test(name)} is handsome." 'hoxis is handsome.'
也能夠直接調用內置函數:
>>> f"{name.lower()} is handsome." 'hoxis is handsome.'
>>> class Person: ... def __init__(self,name,age): ... self.name = name ... self.age = age ... def __str__(self): ... return f"{self.name} is {self.age}" ... def __repr__(self): ... return f"{self.name} is {self.age}. HAHA!" ... >>> hoxis = Person("hoxis",18) >>> f"{hoxis}" 'hoxis is 18' >>> f"{hoxis!r}" 'hoxis is 18. HAHA!' >>> print(hoxis) hoxis is 18 >>> hoxis hoxis is 18. HAHA!
>>> name = 'hoxis' >>> age = 18 >>> status = 'Python' >>> message = { ... f'hi {name}.' ... f'you are {age}.' ... f'you are learning {status}.' ... } >>> >>> message {'hi hoxis.you are 18.you are learning Python.'}
這裏須要注意,每行都要加上 f
前綴,不然格式化會不起做用:
>>> message = { ... f'hi {name}.' ... 'you are learning {status}.' ... } >>> message {'hi hoxis.you are learning {status}.'}
其實,f-string 裏的 f 也許能夠表明 fast
,它比 %格式化方法和 str.format() 都要快:
from timeit import timeit print(timeit("""name = "hoxis" age = 18 '%s is %s.' % (name, age)""", number = 10000)) print(timeit("""name = "hoxis" age = 18 '{} is {}.'.format(name, age)""", number = 10000)) print(timeit("""name = "hoxis" age = 18 f'{name} is {age}.'""", number = 10000))
運行結果:
$ python3.6 fstring.py 0.002238000015495345 0.004068000009283423 0.0015349999885074794
很明顯,f-string 是最快的,而且語法是最簡潔的,是否是火燒眉毛地要試試了?
能夠在字符串中使用各類引號,只要保證和外部的引號不重複便可。
如下使用方式都是沒問題的:
>>> f"{'hoxis'}" 'hoxis' >>> f'{"hoxis"}' 'hoxis' >>> f"""hoxis""" 'hoxis' >>> f'''hoxis''' 'hoxis'
那若是字符串內部的引號和外部的引號相同時呢?那就須要 \
進行轉義:
>>> f"You are very \"handsome\"" 'You are very "handsome"'
若字符串中包含括號 {}
,那麼你就須要用雙括號包裹它:
>>> f"{{74}}" '{74}' >>> f"{{{74}}}" '{74}'
能夠看出,使用三個括號包裹效果同樣。
固然,你能夠繼續增長括號數目,看下有什麼其餘效果:
>>> f"{{{{74}}}}" '{{74}}' >>> f"{{{{{74}}}}}" '{{74}}' >>> f"{{{{{{74}}}}}}" '{{{74}}}'
額,那麼多括號,看着有點暈了...
上面說了,能夠用反斜槓進行轉義字符,可是不能在 f-string 表達式中使用:
>>> f"You are very \"handsome\"" 'You are very "handsome"' >>> f"{You are very \"handsome\"}" File "<stdin>", line 1 SyntaxError: f-string expression part cannot include a backslash
你能夠先在變量裏處理好待轉義的字符,而後在表達式中引用變量:
>>> name = '"handsome"' >>> f'{name}' '"handsome"'
不能在表達式中出現 #
,不然會報出異常;
>>> f"Hoxis is handsome # really" 'Hoxis is handsome # really' >>> f"Hoxis is handsome {#really}" File "<stdin>", line 1 SyntaxError: f-string expression part cannot include '#'
通過以上的講解,是否是發現 f-string
很是簡潔實用、可讀性高,並且不易出錯,能夠嘗試切換到 f-string
嘍~
f-string
也體現出了 Python 的奧義:
>>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
若是以爲有用,歡迎關注個人微信,有問題能夠直接交流,另外提供精品 Python 資料!