python3測試工具開發快速入門教程9重要的標準庫-高級篇

日誌

logging模塊提供了完整和靈活的日誌系統。

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

默認捕獲信息和調試消息不會輸出,輸出爲準錯誤流。可輸出信息到email,數據報文,socket或者HTTP服務器。過濾器可以基於DEBUG、INFO、WARNING、ERROR和CRITICAL選擇不同的路由, 。

日誌系統可以直接在 Python 代碼中定製,也可以不經過應用程序直接在一個用戶可編輯的配置文件中加載。

弱引用

Python自動進行內存管理(對大多數的對象進行引用計數和垃圾回收), 在最後一個引用消失後,內存會很快釋放。

這個工作方式對大多數應用程序工作良好,但是偶爾對象被別的地方使用時會需要跟蹤對象。僅僅爲跟蹤它們創建引用也會使其長期存在。 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:/python36/lib/weakref.py", line 46, in __getitem__
    o = self.data[key]()
KeyError: 'primary'

列表工具

很多數據結構會用到內置列表類型。然而有時可能需要不同性能的實現。

array 塊提供了類似列表的array()對象,它僅僅是存儲數據更緊湊。以下的示例演存儲雙字節無符號整數的數組(類型編碼)"H")而非存儲16字節Python 整數對象的常規列表:

>>> from array import array
>>> a = array('H', [4000, 10, 700, 22222])
>>> sum(a)
26932
>>> a[1:3]
array('H', [10, 700])

collections模塊提供了類似列表的deque()對象,它從左邊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模塊提供了基於常規鏈表的堆實現。最小的值總是保持在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]

參考資料

十進制浮點數算法

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,自動從兩位精度延伸到4位。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')
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章