一、簡介
字符串置換操作。
何謂“簡化”?我們可以先想一下我們之前比較常用的有關字符串的“置換”操作有哪些:一種是利用%操作符實現,另外一種是格式化字符串format實現。那麼,相比於這兩種方法,string.Template究竟簡化在何處呢?
那我們就以下面的代碼為例簡單説明一下string.Template的用法與上述兩種方式的區別:
# -*- coding: utf-8 -*-
# -*- Author: WangHW -*-
import string
values = {'var':3.3333333}
#1
t1 = string.Template("""
Variable : $var
Escape : $$
Variable in text: ${var}iable
""")
print('TEMPLATE:',t1.substitute(values))
print('############################')
#2
s = """
Variable : %(var)s
Escape : %%
Variable in text: %(var)siable
"""
print('INTERPOLATION:',s % values)
print('############################')
#3
s1 = """
Variable {var}
Escape : {{}}
Variable in text: {var}iable
"""
print('FORMAT:',s1.format(**values))
結果如下:
substitute方法取值的。
利用string.Template方法是不需要考慮參數的數據類型的!這是string.Template方法與後面兩種方法最重要的不同之處。string.Template方法直接將參數轉換為字符串格式,然後將轉換後的字符串直接插入結果中去。沒有可用的格式化選項供我們選擇,例如,對於一個浮點數(如上述例子所示)來講,我們沒辦法控制代表這個浮點數數值的位數。
二、safe_substitute方法
上例中我們利用substitute取值。大家肯定會問了:如果$關聯的字符串在前面定義的values中不存在怎麼辦?難道會報錯嗎?
答案是肯定的!為了避免上述問題的產生我們利用safe_substitute方法取值,當然可以跟原生的substitute方法對比一下:
# -*- coding: utf-8 -*-
# -*- Author: WangHW -*-
import string
values = {'var':'foo'}
t = string.Template('$var is here but $missing is not provided')
try:
print('substitute() :',t.substitute(values))
except KeyError as err:
print('ERROR:',str(err))
print('safe_substitute():',t.safe_substitute(values))
結果如下:
values中並沒有代表key的字符串'missing',而我們在Template中卻試圖利用$missing取其對應的值。因此substitute方法會報錯,而safe_substitute方法可以巧妙的“避免”這個錯誤,保證程序的流暢性。
三、進階:模塊功能的“修改”
在實際中,大家可能習慣利用%操作符去進行字符串的置換了,那麼,如果我們既想利用string.Template方法的便捷性,又想按照自己的意願與需求定義額外的功能,這就需要我們新定義一個繼承自string.Template的類(例如命名為MyTempate),在這裏修改其中的某些屬性去滿足我們的需求。
下面代碼中MyTemplate類繼承自string.Template,修改了操作符delimiter與id模式idpattern,實現了利用%關聯代表key的字符串,然後利用正則表達式使safe_substitute()只能匹配出帶下劃線的且由a-z組成的字符串:
# -*- coding: utf-8 -*-
# -*- Author: WangHW -*-
import string
class MyTemplate(string.Template):
#操作符
delimiter = '%'
#id模式
idpattern = '[a-z]+_[a-z]+'
if __name__ == '__main__':
template_text = '''
Delimiter : %%
Replaced : %with_underscore
Ignored : %notunderscored
'''
d = {
'with_underscore':'replaced',
'notunderscored':'not replaced'
}
t = MyTemplate(template_text)
print('Modified ID pattern:')
print(t.safe_substitute(d))
結果如下:
上例中,由於代表key的字符串‘notunderscored’沒有下劃線,沒有匹配到,所以結果中只能得出%notunderscored,不能取到具體的值。
需要注意的是:這種方法在實際中非常常用!在實際中我們需要根據具體的需求靈活的“更改”模塊中某個對象的某個屬性去實現具體的需求!