目錄:
- Python格式化字符串的4中方式
- 一:%號
- 二:str.format
- 三:f-Strings
- 四:標准庫模板
- 五:總結四種方式的應用場景
Python格式化字符串的4種方式
一:%號
%號格式化字符串的方式從Python誕生之初就已經存在,時至今日,python官方也並未棄用%號,但也並不推薦這種格式化方式。
# 1、格式的字符串(即%s)與被格式化的字符串(即傳入的值)必須按照位置一一對應 # ps:當需格式化的字符串過多時,位置極容易搞混 print('%s asked %s to do something' % ('egon', 'lili')) # egon asked lili to do something print('%s asked %s to do something' % ('lili', 'egon')) # lili asked egon to do something # 2、可以通過字典方式格式化,打破了位置帶來的限制與困擾 print('我的名字是 %(name)s, 我的年齡是 %(age)s.' % {'name': 'egon', 'age': 18}) kwargs={'name': 'egon', 'age': 18} print('我的名字是 %(name)s, 我的年齡是 %(age)s.' % kwargs)
二:str.format
該format
方法是在Python 2.6中引入的,是字符串類型的內置方法。因為str.format的方式在性能和使用的靈活性上都比%號更勝一籌,所以推薦使用
2.1 使用位置參數
# 按照位置一一對應 print('{} asked {} to do something'.format('egon', 'lili')) # egon asked lili to do something print('{} asked {} to do something'.format('lili', 'egon')) # lili asked egon to do something
2.2 使用索引
# 使用索引取對應位置的值 print('{0}{0}{1}{0}'.format('x','y')) # xxyx
2.3 使用關鍵字參數or字典
# 可以通過關鍵字or字典方式的方式格式化,打破了位置帶來的限制與困擾 print('我的名字是 {name}, 我的年齡是 {age}.'.format(age=18, name='egon')) kwargs = {'name': 'egon', 'age': 18} print('我的名字是 {name}, 我的年齡是 {age}.'.format(**kwargs)) # 使用**進行解包操作
2.4 填充與格式化
# 先取到值,然后在冒號后設定填充格式:[填充字符][對齊方式][寬度] # *<10:左對齊,總共10個字符,不夠的用*號填充 print('{0:*<10}'.format('開始執行')) # 開始執行****** # *>10:右對齊,總共10個字符,不夠的用*號填充 print('{0:*>10}'.format('開始執行')) # ******開始執行 # *^10:居中顯示,總共10個字符,不夠的用*號填充 print('{0:*^10}'.format('開始執行')) # ***開始執行***
2.5 精度與進制
print('{salary:.3f}'.format(salary=1232132.12351)) #精確到小數點后3位,四舍五入,結果為:1232132.124 print('{0:b}'.format(123)) # 轉成二進制,結果為:1111011 print('{0:o}'.format(9)) # 轉成八進制,結果為:11 print('{0:x}'.format(15)) # 轉成十六進制,結果為:f print('{0:,}'.format(99812939393931)) # 千分位格式化,結果為:99,812,939,393,931
三:f-Strings
str.format() 比 %格式化高級了一些,但是它還是有自己的缺陷。當需要傳入的字符串過多時,仍然會顯得非常冗長。與在Python 3.6中引入 了f-strings,不僅比str.format更簡潔,性能上也更勝一籌
f-
string是以f或F開頭的字符串, 核心在於字符串中符號{}的使用
3.1 {}中可以是變量名
name = 'egon' age = 18 print(f'{name} {age}') # egon 18 print(F'{age} {name}') # 18 egon
3.2 {}中可以是表達式
# 可以在{}中放置任意合法的Python表達式,會在運行時計算 # 比如:數學表達式 print(f'{3*3/2}') # 4.5 # 比如:函數的調用 def foo(n): print('foo say hello') return n print(f'{foo(10)}') # 會調用foo(10),然后打印其返回值 # 比如:調用對象的方法 name='EGON' print(f'{name.lower()}') # egon
3.3 在類中的使用
>>> class Person(object): ... def __init__(self, name, age): ... self.name = name ... self.age = age ... def __str__(self): ... return f'{self.name}:{self.age}' ... def __repr__(self): ... return f'===>{self.name}:{self.age}<===' ... >>> >>> obj=Person('egon',18) >>> print(obj) # 觸發__str__ egon:18 >>> obj # 觸發__repr__ ===>egon:18<=== >>> >>> >>> >>> # 在f-Strings中的使用 >>> f'{obj}' # 觸發__str__ 'egon:18' >>> f'{obj!r}' # 觸發__repr__ '===>egon:18<==='
3.3 多行f-Stings
# 當格式化字符串過長時,如下列表info name = 'Egon' age = 18 gender = 'male' hobbie1='play' hobbie2='music' hobbie3='read' info = [f'名字:{name}年齡:{age}性別:{gender}',f'第一個愛好:{hobbie1}第二個愛好:{hobbie2}第三個愛好:{hobbie3}'] # 我們可以回車分隔到多行,注意每行前都有一個f info = [ # 第一個元素 f'名字:{name}' f'年齡:{age}' f'性別:{gender}', # 第二個元素 f'第一個愛好:{hobbie1}' f'第二個愛好:{hobbie2}' f'第三個愛好:{hobbie3}' ] print(info) # ['名字:Egon年齡:18性別:male', '第一個愛好:play第二個愛好:music第三個愛好:read']
3.4 引號的嵌套
# 當字符串嵌套發送沖突時,與正常的字符串處理方式是一樣的 # 1、外層為單引號,內層嵌套也為單引號,並且想要輸入的內容也為單引號,那么外層需要改用雙引號 print("my name is 'egon'") # 2、外層為單引號,內層嵌套也為單引號,並且想要輸入的內容也為單引號,需要用到轉義 print('my name is \'egon\'')
3.5注意
#1、反斜杠可以用來進行字符轉義,但不能用在{}的表達式中 f'{1\2}' # 語法錯誤 #2、注釋#號也不能出現在{}的表達式中 f'{x#}' # 語法錯誤
3.6 括號的處理
基於3.5我們得知,不能在{}內出現反斜杠\,所以,當我們的輸出的結果中需要包含{}時,下面的做法就是錯誤的
print(f'\{天王蓋地虎\}')
類似於輸出%號的做法
>>> print('%s%%' %30)
30%
若想輸出{},那么需要在原有的基礎上再套一層,如下
print(f'{{天王蓋地虎}}') # {天王蓋地虎} print(f'{{{{天王蓋地虎}}}}') # {{天王蓋地虎}}
性能對比=>f_Stings性能最高
from timeit import timeit def test_s(): name = 'Egon' age = 18 return '%s:%s.' % (name, age) def test_format(): name = 'Egon' age = 18 return '{}:{}.'.format(name, age) def test_f_strings(): name = 'Egon' age = 18 return f'{name}:{age}.' res1 = timeit(test_s, number=1000000) res2 = timeit(test_format, number=1000000) res3 = timeit(test_f_strings, number=1000000) print(res1) # 0.3709844550030539 print(res2) # 0.47834375899401493 print(res3) # 0.3111891380031011, 最快
四:標准庫模板
從Python 2.4起,Python標准庫string引入了Template也可以用來格式化字符串,所以說,與前三種方式的一個顯著區別就是:Template並屬於python語言的核心語法特征,使用方式如下
from string import Template name='EGON' t = Template('Hello $name!') res=t.substitute(name=name) print(res) # Hello EGON!
另外一個不同的地方是這個模板字符串不支持類似str.format那樣的進制轉換,需要我們自己處理
from string import Template name='EGON' templ_string = 'Hello $name, there is a $error error!!!' res=Template(templ_string).substitute(name=name, error=hex(12345)) print(res) # Hello EGON, there is a 0x3039 error!!!
使用模板字符串Template的最佳的時機就是當你的程序需要處理由用戶提供的輸入內容時。模板字符串是最保險的選擇,因為可以降低復雜性。
其他一些復雜的字符串格式化技巧的可能會給你的程序帶來安全漏洞
五:總結四種方式的應用場景
1、如果格式化的字符串是由用戶輸入的,那么基於安全性考慮,推薦使用Template
2、如果使用的python3.6+版本的解釋器,推薦使用f-Stings
3、如果要兼容python2.x版本的python解釋器,推薦使用str.format
4、如果不是測試的代碼,不推薦使用%