python中的formatter的詳細用法


今天抽空學習了一下python中的string service中的formatter的相關用法,主要是為了讓自己的代碼看起來更加和諧,因為很多java或者c語言過來的開發者都不怎么愛使用python的原生的字符串格式化工具,似乎大家都愛用下面的格式化工具

info = 'my name is %s I really enjoy %s' % ('younger', 'python')

現在我要學習使用更加python化的字符串格式化風格。

python的buildin字符串服務模塊 [string](file:///Users/youngershen-mac-book-pro/Downloads/python-2.7.8-docs-html/library/string.html) 本身提供了一些字符串操作的工具類方法,其中包括一些經常會使用到的常量,和比較復雜的Formatter類,Template類,這里我要重點學習的就是string.Formatter類

[string.Formatter](file:///Users/youngershen-mac-book-pro/Downloads/python-2.7.8-docs-html/library/string.html#string-formatting)類中的方法:

format(format_string, *args, **kwargs)
format方法是string.Formatter類中的主要方法,它的參數是一個你需要去格式化的目標字符串,和一組需要去填充目標字符串的序列,比如字典和元組,format方法是對vformat方法的封裝。

上面是我照文檔的說明寫的,其實Formatter.format方法和str.format並沒有什么不同,他們的語法是通用的,只要學會一種就都會了,哪個更方便就用哪個
vformat(format_string, args, kwargs)
parse(format_string)
get_field(field_name, args, kwargs)
get_value(key, args, kwargs)
上面的這幾個方法是互相調用的,所以一放在一起研究,其中Formatter.format 最終調用的是Formatter.vformat方法,測試程序如下

class Person(object):
	name  = 'default name'
	def __init__(self, name = ''):
		self.name = name
me = Person('younger')
data = [me]
s = "my name is {person[0].name:^30}"
formatter = String.Formatter()
formatter.format(s, data)
輸出結果:
>>> formatter.format(s, person = data)
'my name is            younger            '

現在用Formatter.vformat方法
formatter.vformat(s, (), {'person' : data})
輸出結果:
>>> formatter.format(s, person = data)
'my name is            younger            '

2個方法的結果是完全一樣的,只是一個包裝了另一個,再Formatter.vformat方法中必須有4個參數,中間的空元組和最后的空字典必須存在,因為Formatter.vformat的參數不是 (*args, **kwargs) 而是 (args, kwargs), 這是完全不一樣的,沒看清楚會悲劇的。

現在繼續說上面4個方法的調用順序, get_value調用了get_field, get_field調用parse, vformat調用了  get_value, 一般情況下我們只需要調用format就足夠了,上面的4個方法都是給需要繼承Formatter創建自己的格式化語法的時候來覆蓋掉的,不過我們可以從這4個方法分析出很多東西。

我現在執行下面的程序
for i, v in enumerate(formatter.parse(s, start = 0)):
	print i, v
結果會輸出:
0 ('my name is ', 'person[0].name', '^30', None)
上面是返回的第1個編號為0的元組, 這4個值分別是 
(literal_text, field_name, format_spec, conversion)
我們沒有canversion, 所以第4項是None, 你也可以寫上一個!r或者!s
這樣的話字符串就變成了
s = "my name is {person[0].name!r:^30}"
前兩項都很好理解,直接看字面就懂什么意思,第三項的意思是說格式化的時候的站位符,我這里用的是空,你也可以用星號,現在把s變成這樣
s ="my name is {person[0].name!r:*^30}"
輸出的結果是:
"my name is **********'younger'***********"
*號充當了占位符的作用

現在執行下面的程序:
for i ,v in enumerate(formatter.parse(s)):
	temp = v

formatter.get_field(temp[1], (), {'person' : data})
輸出結果為:
('younger', 'person')
用文檔中的話來說就是 'object'和'used_key', 這個key和get_value中的key是相同的所以要調用get_value必須先調用get_field
下面繼續執行代碼
ret = formatter.get_value(formatter.get_field(temp[1], (), {'person':data})[1], (), {'person':data})
這個返回的 ret就是得到的對象,一個Person類型的list ,里面只有一個對象就是最初我們填充的那個,到此為止 , 所有的方法都跑了一遍,如果我們要改寫自己的format語法,那就直接繼承這個類,覆蓋這么幾個方法就行了,其余的2個方法很容易理解,可以直接看文檔。

Formatter.format的語法

這里就不采用文檔里的論道的方法來說明了,直接以我的理解來說好了

只有keyword類型的format string
最簡單的:
"my name is {name}".format(name = 'younger')
帶有多個組合條件的
"my name is {person[0].name!r:*^30}".format(person = data_list)
上面的意思是說傳入的是一個list,list中有person, keyword是person[0].name, 很好理解,就是第0個對象的name屬性, 這樣用起來很方便, 非常好記, 從!r開始的奇怪語法是 Format Specification Mini-Language , 其中對一些數據類型,比如百分數,正負數, 復數, 大數,時間,小數點的位數,以及格式化format string的站位符等進行了定義,用法都和我寫的例子一樣,沒有什么復雜的,這里例子已經算是比較復雜的例子了。
只有position類型的format string
"my name is {0.name}".format(person)
同時有position和keyword的formart string
"my name is {0.name}, I am living at {area[0].city}".format(person, area_list)
這里要注意的就是position的必須寫再前面,不然是不能使用的,推薦大家一個格式化字符串里只用以個方式去寫。


免責聲明!

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



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