Python3.4 Tutorial11 - Brief Tour of the Standard Library – Part II
11 標準庫簡介 - 第二部分
第二部分的瀏覽包含更多的高階模組,可以支援專業的程式設計需要。這些模組很少出現在小段的指令碼中。
11.1 輸出格式化
reprlib
模組提供repr()
的一個定製版本,它專門用於縮排顯示大型或深層巢狀的容器:
>>> import reprlib >>> reprlib.repr(set('supercalifragilisticexpialidocious')) "set(['a', 'c', 'd', 'e', 'f', 'g', ...])"
pprint
模組提供了更復雜的控制系統,在直譯器可以讀到(定義內容)的情況下,它可以列印出內建物件和使用者自定義物件的定義文字。當結果超過一行的時候,“列印美化”功能會新增換行符和縮排使資料的結構更加清晰可見:
>>> import pprint >>> t = [[[['black', 'cyan'], 'white', ['green', 'red']], [['magenta', ... 'yellow'], 'blue']]] ... >>> pprint.pprint(t, width=30) [[[['black', 'cyan'], 'white', ['green', 'red']], [['magenta', 'yellow'], 'blue']]]
textwrap
模組可以格式化段落文字,使它們適應指定的螢幕寬度:
>>> import textwrap >>> doc = """The wrap() method is just like fill() except that it returns ... a list of strings instead of one big string with newlines to separate ... the wrapped lines.""" ... >>> print(textwrap.fill(doc, width=40)) The wrap() method is just like fill() except that it returns a list of strings instead of one big string with newlines to separate the wrapped lines.
locale
模組可以訪問記錄了不同文化下資料格式差異的資料庫。locale
中格式化函式的分組屬性,提供了使用一組分隔符來直接格式化數字的方式:
>>> import locale >>> locale.setlocale(locale.LC_ALL, 'English_United States.1252') 'English_United States.1252' >>> conv = locale.localeconv() # get a mapping of conventions >>> x = 1234567.8 >>> locale.format("%d", x, grouping=True) '1,234,567' >>> locale.format_string("%s%.*f", (conv['currency_symbol'], ... conv['frac_digits'], x), grouping=True) '$1,234,567.80'
11.2 模板(Templating)
string
模組包含一個多功能的Template
類,它簡化的語法適合終端使用者的編輯需要。這允許使用者定製他們的應用而不要修改應用內容。
格式化操作使用$加合法的Python標誌符(包括字母、數字和下劃線)作為佔位符。在佔位符周圍加上花括號,可以在後面跟著其他字母或數字而不用插入空格。可以使用$$
來轉義$
:
>>> from string import Template >>> t = Template('${village}folk send $$10 to $cause.') >>> t.substitute(village='Nottingham', cause='the ditch fund') 'Nottinghamfolk send $10 to the ditch fund.'
如果佔位符需要的資料沒有在字典或關鍵字引數中提供,substitute()
方法會引發一個KeyError
。在mail-merge風格的應用中,使用者提供的資料可能不全,這是使用safe_substitute()
方法會更合適——當沒有提供資料時,會原樣顯示佔位符:
>>> t = Template('Return the $item to $owner.') >>> d = dict(item='unladen swallow') >>> t.substitute(d) Traceback (most recent call last): ... KeyError: 'owner' >>> t.safe_substitute(d) 'Return the unladen swallow to $owner.'
Template的子類可以自己指定一個分隔符。例如,一個圖片瀏覽器的批量重新命名工具,可能選擇百分號作為佔位符用於表示當前日期、圖片序列號或檔案格式等:
>>> import time, os.path >>> photofiles = ['img_1074.jpg', 'img_1076.jpg', 'img_1077.jpg'] >>> class BatchRename(Template): ... delimiter = '%' >>> fmt = input('Enter rename style (%d-date %n-seqnum %f-format): ') Enter rename style (%d-date %n-seqnum %f-format): Ashley_%n%f >>> t = BatchRename(fmt) >>> date = time.strftime('%d%b%y') >>> for i, filename in enumerate(photofiles): ... base, ext = os.path.splitext(filename) ... newname = t.substitute(d=date, n=i, f=ext) ... print('{0} --> {1}'.format(filename, newname)) img_1074.jpg --> Ashley_0.jpg img_1076.jpg --> Ashley_1.jpg img_1077.jpg --> Ashley_2.jpg
模板化的另一個應用是,將程式邏輯從多樣化輸出格式化的細節中分離出來。這使得使用自定義模板替代XML檔案、純文字報表和HTML網頁報表成為可能。
11.3 使用二進位制資料記錄佈局
struct
模組提供了pack()
和unpack()
函式,用來處理不定長二進位制記錄的格式化。下面的例子展示瞭如何不使用zipfile
模組遍歷Zip檔案頭資訊。打包程式碼中"H"
和"I"
分別代表2byte和4byte的無符號數字。"<"
符號代表它們使用標準大大小並且使用小端位元組序:
import struct with open('myfile.zip', 'rb') as f: data = f.read() start = 0 for i in range(3): # show the first 3 file headers start += 14 fields = struct.unpack('<IIIHH', data[start:start+16]) crc32, comp_size, uncomp_size, filenamesize, extra_size = fields start += 16 filename = data[start:start+filenamesize] start += filenamesize extra = data[start:start+extra_size] print(filename, hex(crc32), comp_size, uncomp_size) start += extra_size + comp_size # skip to the next header
11.4 多執行緒
執行緒是一種將不依賴執行順序的任務解耦的技術。其他任務在後臺執行時,執行緒可以用來改善應用程式對使用者輸入的響應性。一個相關的用例是,可以是I/O和另一個執行緒中的計算併發執行。
下面的程式碼展示了高層的threading
模組,怎樣在主程式繼續執行時在後臺執行任務:
import threading, zipfile class AsyncZip(threading.Thread): def __init__(self, infile, outfile): threading.Thread.__init__(self) self.infile = infile self.outfile = outfile def run(self): f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED) f.write(self.infile) f.close() print('Finished background zip of:', self.infile) background = AsyncZip('mydata.txt', 'myarchive.zip') background.start() print('The main program continues to run in foreground.') background.join() # Wait for the background task to finish print('Main program waited until background was done.')
多執行緒應用程式最重要的挑戰是,協調執行緒間的共享資料或其他資源。為此,threading模組提供了許多原語,包括鎖(locks)、事件(events)、條件變數(condition variables)、訊號量(semaphores)。
雖然那些工具很強大,但是微小的設計錯誤可能導致難以復現的問題。所以,協調任務的首選方案是將所有資源訪問都集中在一個執行緒中,然後使用queue模組來處理來自其他執行緒的請求。應用程式使用Queue物件處理執行緒間的通訊和協調,可以使設計更簡單,可讀性、可靠性更高。
11.5 日誌
logging
模組提供了一個完善而靈活的日誌系統。最簡單的,日誌訊息會被輸出到一個檔案或sys.stderr中的:
import logging logging.debug('Debugging information') logging.info('Informational message') logging.warning('Warning:config file %s not found', 'server.conf') logging.error('Error occurred') logging.critical('Critical error -- shutting down')
這會產生以下輸出:
WARNING:root:Warning:config file server.conf not found ERROR:root:Error occurred CRITICAL:root:Critical error -- shutting down
預設情況下,資訊和除錯訊息會被抑制,並且它們是被髮送到標準錯誤流中輸出。其他的輸出選項包括經由郵件、資料包、套接字的路由訊息或者是傳送給一個HTTP伺服器。新的過濾器可以根據訊息的優先順序選擇不同的路由,優先順序有:DEBUG、INFO、WARNING,、ERROR和CRITICAL。
日誌系統可以在不改變應用程式的情況下,直接通過Python進行配置,也可以載入一個使用者可編輯的配置檔案來定製日誌內容。
11.6 弱引用(Weak References)
Python會自動進行記憶體管理(為大多數物件進行引用計數,週期性進行垃圾回收)。在最後一個引用消失後不久記憶體就會被釋放。
這種機制適用於大多數應用程式, 但也有偶然情況, 只有當它們被其它東西使用時才需要去跟蹤物件。不幸的是,僅是要追蹤它們也需要建立的一個引用,這會使它們永久存在(翻譯的可能有誤,原文:just tracking them creates a reference that makes them permanent)。weakref
模組提供了不建立引用就可以跟蹤物件的工具。當物件不再需要時,它自動從弱引用表中刪除並通過回撥觸發弱引用物件。典型的應用包括快取那些建立開銷大的物件:
>>> import weakref, gc >>> class A: ... def __init__(self, value): ... self.value = value ... def __repr__(self): ... return str(self.value) ... >>> a = A(10) # create a reference >>> d = weakref.WeakValueDictionary() >>> d['primary'] = a # does not create a reference >>> d['primary'] # fetch the object if it is still alive 10 >>> del a # remove the one reference >>> gc.collect() # run garbage collection right away 0 >>> d['primary'] # entry was automatically removed Traceback (most recent call last): File "<stdin>", line 1, in <module> d['primary'] # entry was automatically removed File "C:/python34/lib/weakref.py", line 46, in __getitem__ o = self.data[key]() KeyError: 'primary'
11.7 使用Lists的工具
對很多資料結構的需求都可使用內建的list型別來滿足。然而,有時候需要在不同的效能權衡中選擇一種實現方式。
array
模組提供了一個array()
物件,就像一個list,可以儲存同一型別的資料並且更緊湊(這裡應該是指記憶體開銷小)。下面這個例子演示了將一組數字以2byte的無符號二進位制數(型別碼 "H"
) 形式儲存為一個array,而不是常規的list儲存的每項16byte的Python整數物件(原文:The following example shows an array of numbers stored as two byte unsigned binary numbers (typecode "H") rather than the usual 16 bytes per entry for regular lists of Python int objects):
>>> from array import array >>> a = array('H', [4000, 10, 700, 22222]) >>> sum(a) 26932 >>> a[1:3] array('H', [10, 700])
collections
模組提供了一個deque()
物件,和list類似,但是它在左側的append、pop操作速度快,在中間的查詢很慢。這些物件適合實現佇列和廣度優先樹的查詢:
>>> from collections import deque >>> d = deque(["task1", "task2", "task3"]) >>> d.append("task4") >>> print("Handling", d.popleft()) Handling task1
</>
unsearched = deque([starting_node]) def breadth_first_search(unsearched): node = unsearched.popleft() for m in gen_moves(node): if is_goal(m): return m unsearched.append(m)
除了選擇不同的連結串列實現之外,這個庫還提供了其他工具,例如bisect
模組帶有操作連結串列排序的函式:
>>> import bisect >>> scores = [(100, 'perl'), (200, 'tcl'), (400, 'lua'), (500, 'python')] >>> bisect.insort(scores, (300, 'ruby')) >>> scores [(100, 'perl'), (200, 'tcl'), (300, 'ruby'), (400, 'lua'), (500, 'python')]
heapq
模組提供了一些基於常規list實現堆的函式。輸入的最小的值總是保持在位置0處。這對於重複訪問最小的元素但又不想對整個列表進行排序的應用程式來說十分有用:
>>> from heapq import heapify, heappop, heappush >>> data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0] >>> heapify(data) # rearrange the list into heap order >>> heappush(data, -5) # add a new entry >>> [heappop(data) for i in range(3)] # fetch the three smallest entries [-5, 0, 1]
11.8 十進位制浮點運算
decimal
模組提供了一個Decimal
資料型別,用於十進位制浮點運算。相比於使用二進位制浮點實現的內建float
型別,這個類在下列情況中特別有用:
- 金融應用和其他需要精確十進位制表示的地方
- 需要精度控制
- 需要控制四捨五入,以滿足法律或監管的要求
- 需要跟蹤有意義的小數部分
- 使用者期望應用的結果和手動計算的結果相匹配
例如,在計算70美分話費的5%的稅收時,十進位制浮點數和二進位制浮點數的結果是不同的。如果結果以美分的精讀進行舍入的話,這個差別就會變得很重要:
>>> from decimal import * >>> round(Decimal('0.70') * Decimal('1.05'), 2) Decimal('0.74') >>> round(.70 * 1.05, 2) 0.73
Decimal
結果會保持尾部的0,並會從兩位有效數字的數乘中自動推匯出思維有效數字。Decimal再現手工數學運算的精讀,避免二進位制浮點小數點不能準確地表示十進位制數時出現的問題。
高精度使的Decimal類可以去做那些二進位制浮點數不適合的模運算和相等測試:
>>> Decimal('1.00') % Decimal('.10') Decimal('0.00') >>> 1.00 % 0.10 0.09999999999999995 >>> sum([Decimal('0.1')]*10) == Decimal('1.0') True >>> sum([0.1]*10) == 1.0 False
decimal
可以滿足你所需要的算術精讀:
>>> getcontext().prec = 36 >>> Decimal(1) / Decimal(7) Decimal('0.142857142857142857142857142857142857')
相關文章
- Python3.4 Tutorial10 - Brief Tour of the Standard LibraryPython
- Go Standard library - flagGo
- Go Standard library - stringsGo
- Python3.4 Tutorial9 - Classes (Part 3)Python
- Python3.4 Tutorial9 - Classes (Part 4)Python
- Python3.4 Tutorial9 - Classes (Part 2)Python
- Python3.4 Tutorial9 - Classes (Part 1)Python
- C++ Standard Library擴充建議... (轉)C++
- 「譯」MotionLayout 介紹 (part II)
- Business Objects Query Builder – Part IIObjectUI
- Delphi物件模型(Part II) (轉)物件模型
- Beyond the C++ Standard Library電子書pdf下載C++
- 演算法競賽向 C++ Standard Library 使用速查演算法C++
- 【做題記錄】ds合集 Part II
- Structure of Linux Kernel Device Driver(Part II)StructLinuxdev
- 前端測試:Part II (單元測試)前端
- oracle administrator's guide Part IIOracleGUIIDE
- On Designing Good Libraries -- Part II (轉)Go
- 什麼BRIEF演算法?BRIEF演算法詳解演算法
- Part II 診斷和優化資料庫效能優化資料庫
- React + Koa 實現服務端渲染(SSR) Part IIReact服務端
- oracle database backup and recovery user's guide part I & IIOracleDatabaseGUIIDE
- A tour of Go例程疑惑Go
- error: #error This file requires compiler and library support for the ISO C++ 2011 standard.ErrorUICompileC++
- a brief history of AI: reign of chaosAI
- Part II 建立和配置CDB-Oracle多租戶管理員指南Oracle
- 安裝golang tour,提示錯誤Golang
- A Brief Introduce of Database Index(索引簡介)DatabaseIndex索引
- A Brief Look at C++ 中文版 (轉)C++
- Standard Database AuditingDatabase
- POJ 3007-Organize Your Train part II(hash-字串)AI字串
- 幾乎所有基於Java的web app都需要Model 2 (part II) (轉)JavaWebAPP
- python3.4之決策樹Python
- abc369E Sightseeing Tour
- Python3.5.2 document學習系列之03、The Python Standard Library(python 標準庫)——內建函式Python函式
- C++ coding standardC++
- .NET Standard是什麼
- python3.4支援xp麼Python