這里我們將對Python 3.1核心語言的變化進行分析,包括字符串的格式化、說明符以及其他方面的內容。希望這些變化能對大家了解Python 3.1有所幫助。
Python 3.0發布七個月之后,Python核心開發人員于2009年6月27日發布了新的Python 3.1版本。雖然此3.1版本只是對Python 3.0的一次小型升級,但是它不僅為開發者帶來許多讓人感興趣的特性,同時在性能方面也有所改善。本文將為讀者詳細介紹Python 3.1版本在核心語言、標準程序庫和性能改善方面的變化。
一、字符串的格式化
Python的最新版本為我們帶來了討人喜歡的格式字段的自動填數功能。我們知道,許多程序中經常需要格式化字符串。Python 2.x版本使用的是類似[s]printf函數的百分號操作符,如下所示:
>>> '%s, %s!' % ('Hello', 'World') 'Hello, World!'而Python 3.0則添加了更高級的字符串格式化功能,如下所示:
>>> '{0}, {1}!'.format('Hello', 'World') 'Hello, World!'如今,Python 3.1則在字符串格式化方面又有了新的改進。對于Python 3.0來說,每當您想在格式串中引用位置參數時,您必須給出每個位置參數的索引。但是在Python 3.1中,您就可以將這些索引拋在腦后了,因為Python會依次替您填充這些參數:
>>> '{}, {}!'.format('Hello', 'World') 'Hello, World!' 二、PEP-378:用于千位分隔符的格式說明符
在財務應用程序中,通常要在數字中使用千位分隔符。從事金融或者財會方面工作的人士是不這樣寫的“您欠我$12345678”,而是“您欠我$12,345,678”,他們慣于使用逗號作為分隔符。那么,如何使用Python達到這種效果呢:
>>> format(12345678, ',')
'12,345,678'您可以利用其他區分符對數字進行分組。這里的寬度說明符(這里為8)包括了逗號和小數點:
>>> format(1234, ',').replace(',', '_') '12,345.7'逗號通常作為默認的分隔字符,如果要使用其他字符作為分隔字符的話,只需通過replace函數用您喜歡的字符替換逗號即可,具體如下所示:
>>> format(1234, ',').replace(',', '_') '1_234'當然,您還可以使用format函數來作為字符串方法:
>>> '{0:8,.1f}'.format(123.456)三、Maketrans函數
利用maketrans()和translate()函數,我們可以使用一組字符來替換另一組字符。使用這一替換功能時,多少有點繁瑣,因為它要求使用maketrans()函數(該函數的作用是把輸入字符映射到輸出字符)建立一個轉換表,然后,再把這個轉換表傳遞給translate()函數。當然,string模塊仍然有它自己的maketrans()函數,不過Python 3.1不贊成使用它,而是贊賞使用單獨的maketrans()函數來操作字節、字節數組和字符串。
下面的例子演示了如何使用maketrans()和translate()函數處理字節對象。需要注意的是,用于字節的轉換表具有256個表項(每一項對應于一個可能的字節),并且這個例子把大部分字節都映射到它們自身,只有1,2和3例外,因為它們分別映射到了4,5和6。如下所示:
>>> tt = bytes.maketrans(b'123', b'456') >>> len(tt) 256 >>> tt b'/x00/x01/x02/x03/x04/x05/x06/x07/x08/ t/n/x0b/x0c/r/x0e/x0f/x10/x11/x12/x13/ x14/x15/x16/x17/x18/x19/x1a/x1b/x1c/x1d/ x1e/x1f !"#$%&/'()*+,-./0456456789:;<=> ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[//]^_`abcd efghijklmnopqrstuvwxyz{|}~/x7f/x80/x81/ x82/x83/x84/x85/x86/x87/x88/x89/x8a/x8b/ x8c/x8d/x8e/x8f/x90/x91/x92/x93/x94/x95/ x96/x97/x98/x99/x9a/x9b/x9c/x9d/x9e/x9f/ xa0/xa1/xa2/xa3/xa4/xa5/xa6/xa7/xa8/xa9/ xaa/xab/xac/xad/xae/xaf/xb0/xb1/xb2/xb3/ xb4/xb5/xb6/xb7/xb8/xb9/xba/xbb/xbc/xbd/ xbe/xbf/xc0/xc1/xc2/xc3/xc4/xc5/xc6/xc7/ xc8/xc9/xca/xcb/xcc/xcd/xce/xcf/xd0/xd1/ xd2/xd3/xd4/xd5/xd6/xd7/xd8/xd9/xda/xdb/ xdc/xdd/xde/xdf/xe0/xe1/xe2/xe3/xe4/xe5/ xe6/xe7/xe8/xe9/xea/xeb/xec/xed/xee/xef/ xf0/xf1/xf2/xf3/xf4/xf5/xf6/xf7/xf8/xf9/ xfa/xfb/xfc/xfd/xfe/xff' 建好轉換表之后,我們只需把它傳遞給translate()函數即可,如下所示:
>>> b'123456'.translate(tt)
b'456456'我們還可以傳遞其它的參數作為要刪除的字符:
>>> b'123456'.translate(tt, b'5')
b'45646'我們可以看到,原來的5已經從123456從刪掉了,但是轉換得到的5(請記住,我們的映射表將2轉化為5)并沒有刪除。這說明,系統是先從原來的字符串中刪除相應的字符,然后才進行的轉換操作。
字符串的轉換稍微有些不同,字符串版本的maketrans函數返回的是一個字典:
>>> tt = str.maketrans('123', '456') {49: 52, 50: 53, 51: 54} >>> '123456'.translate(tt) '456456' 四、與數學有關的變化
>>> int.bit_length(19) 5 >>> bin(19)
3.1版本在與數學有關的方面也有所改變。
Int添加了一個bit_length方法
新版本中,int變量具有一個bit_length方法,它能返回該int變量以二進制數表示的時候的位數。例如,數字19的二進制表示為10011,那么它的位數就是5:
'0b10011'浮點數的舍入
在Python 3.0以及早先的round()函數有點反復無常:如果您不指定精度的時候,它返回的是一個整數;如果指定精度的話,它返回的是您輸入數據的類型:
>>> round(1000) 1000 >>> round(1000.0) 1000 >>> round(1000, 2) 1000 >>> round(1000.0, 2)
1000.0在Python 3.1中,只要輸入的數字是一個整數(即使它是用浮點數的形式表示的,例如1000.0),那么它總是返回一個整型數:
>>> round(1000) 1000 >>> round(1000.0) 1000 >>> round(1000, 2) 1000 >>> round(1000.0, 2)
1000浮點數的表示
目前,實數在大部分的硬件和操作系統中都是用32位(單精度)或者64位(雙精度)來表示的。然而,這會導致一些實數無法精確表示。由于計算機存儲器的二進制特性,某些數字利用十進制表示形式非常簡潔,但是要是使用浮點方案表示的話,就要復雜了。舉例來說,利用32位的單精度浮點數表示數字0.6,則為0.59999999999999998:
>>> 0.6
0.59999999999999998對于這種表示方案,上面的數字是為了做到盡可能的精確,但是對用戶來說卻很不友好。 Python 3.1使用了一個新算法,以便使得原值的表示盡可能得簡練。所以在Python 3.1中,人們輸入上面的數字,一個更簡潔的表示:
>>> 0.6
0.6這已經很精確了,除非遇到算術運算。舉例來說,表達式0.7+0.1的值用32位浮點表示法表示的話,它是 0.79999999999999993,而數字0.8的值用32位浮點數表示則是 0.80000000000000004。 這樣一來,就意味著0.7+0.1并不等于0.8,這會導致一些問題。例如,下面的循環將永不休止:
>>> x = 0.0 >>> while x != 1.0: ... print(repr(x)) ... x += 0.1輸出的結果: 0 0.10000000000000001 0.20000000000000001 0.30000000000000004 0.40000000000000002 0.5 0.59999999999999998 0.69999999999999996 0.79999999999999993 0.89999999999999991 0.99999999999999989 1.0999999999999999 1.2 1.3 1.4000000000000001 1.5000000000000002 1.6000000000000003
...在Python 3.0中,repr()函數返回的是實際表示;而在Python 3.1中,它返回的是簡潔表示。無論是在Python 3.0還是在Python 3.1中,print()函數顯示的都是簡潔表示:
>>> print(0.1) 0.1 >>> print(0.10000000000000001)
0.1Python語言還有一個稱為decimal的模塊,可用于精確的實數表示。它使用一個不同的表示方案來表示浮點數,并且在內存運行的情況下,用盡量多的數位來表示一個實數――并且,當進行算術的時候不會出現舍入誤差。在Python 3.0中,Decimal類型使用了一種新方法來從一個字符串初始化它表示的值;在Python 3.1中,又增加了另一個新方法即from_float()來接收浮點數。注意,即使當使用from_float()的時候,Decimal模塊也會比32位更精確。
>>> from decimal import Decimal >>> Decimal.from_float(0.1) Decimal('0.1000000000000000055511151231257827021181583404541015625') 五、改進的WITH語句
在Python 2.5中,WITH語句是作為一個__future__特性引入的,該語句的正式引入實際上是從Python 3.0開始的。到了Python 3.1版本,該語句已經能夠支持更多的資源。最常見的情形是,它可以打開輸入、輸出文件并在處理完成后關閉它們。在Python 3.0中,我們要么使用嵌套的with語句,要么顯式閉合在文件中。下面是一個Python 3.0的例子,它打開了一個輸入文件,將其內容作為字符串讀取,用字符串的title()方法處理內容,并將結果寫到一個輸出文件中。
這個示例中含有兩個嵌套的with語句,注意嵌套的with語句中的最后一行。當代碼試圖讀取out.txt的時候,結果為空,因為此文件是被緩沖處理的,并且還沒有寫入。當此with語句完成的時候,Python會關閉此文件,所以最后一行代碼會認定out.txt的內容的確是大寫文字。
open('in.txt', 'w').write('abc def') with open('in.txt') as in_file: with open('out.txt', 'w') as out_file: text = in_file.read() assert text == 'abc def' text = text.title() assert text == 'Abc Def' out_file.write(text) assert open('out.txt').read() == '' assert open('out.txt').read() == 'Abc Def'看到嵌套的with語句,是不是感覺有點頭疼,呵呵。接下來,我們要打開兩個兩個文件,并在處理完成后關閉它們(如果您需要打開三個文件,那么就需要三個嵌套的with語句)。 Python 3.1運行您使用單個WITH語句打開所有文件:
open('in.txt', 'w').write('abc def') with open('in.txt') as in_file: with open('out.txt', 'w') as out_file: text = in_file.read() assert text == 'abc def' text = text.title() assert text == 'Abc Def' out_file.write(text) assert open('out.txt').read() == '' assert open('out.txt').read() == 'Abc Def' Python 3.1的另一項改進就是,gzip.GzipFile和bz2.BZ2File現在也能用于WITH語句。我們知道,這些都是壓縮后的文件格式。下面的示例代碼將使用gzip文件和bz2文件來存儲5000個字節的內容,并顯示其尺寸。這里還有用到一些額外的Python 3特性,比如帶有命名屬性的統計結果和高級字符串格式化。
from bz2 import BZ2File from gzip import GzipFile import os with GzipFile('1.gz', 'wb') as g, BZ2File('1.bz2', 'wb') as b: g.write(b'X' * 5000) b.write(b'X' * 5000) for ext in ('.gz', '.bz2'): filename = '1' + ext print ('The size of the {0} file is {1.st_size} bytes'.format(ext, os.stat(filename)))輸出的結果: The size of the .gz file is 43 bytes The size of the .bz2 file is 45 bytes 六、小結
Python 3.0發布七個月之后,Python核心開發人員于2009年6月27日發布了新的Python 3.1版本。雖然此3.1版本只是對Python 3.0的一次小型升級,但是它不僅為開發者帶來許多讓人感興趣的特性,同時在性能方面也有所改善。本文為讀者詳細介紹了Python 3.1版本在核心語言方面的變化,在接下來的文章中,我們將繼續為讀者介紹新版本中標準程序庫和性能改善方面的變化。
新聞熱點
疑難解答
圖片精選