Python學習之常用模組

stonezhu發表於2018-06-24

Python學習目錄

  1. 在Mac下使用Python3
  2. Python學習之資料型別
  3. Python學習之函式
  4. Python學習之高階特性
  5. Python學習之函數語言程式設計
  6. Python學習之模組
  7. Python學習之物件導向程式設計
  8. Python學習之物件導向高階程式設計
  9. Python學習之錯誤除錯和測試
  10. Python學習之IO程式設計
  11. Python學習之程式和執行緒
  12. Python學習之正則
  13. Python學習之常用模組
  14. Python學習之網路程式設計

Python之所以自稱“batteries included”,就是因為內建了許多非常有用的模組,無需額外安裝和配置,即可直接使用。

常用模組

常用內建模組

datetime

datetime是Python處理日期和時間的標準庫。

>>> from datetime import datetime
>>> dt = datetime(2015, 4, 19, 12, 20) # 用指定日期時間建立datetime
>>> dt.timestamp() # 把datetime轉換為timestamp
1429417200.0
複製程式碼

注意Python的timestamp是一個浮點數。如果有小數位,小數位表示毫秒數。

collections

collections是Python內建的一個集合模組,提供了許多有用的集合類。

namedtuple

>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(1, 2)
>>> p.x
1
>>> p.y
2
複製程式碼

namedtuple是一個函式,它用來建立一個自定義的tuple物件,並且規定了tuple元素的個數,並可以用屬性而不是索引來引用tuple的某個元素。

這樣一來,我們用namedtuple可以很方便地定義一種資料型別,它具備tuple的不變性,又可以根據屬性來引用,使用十分方便。

deque

使用list儲存資料時,按索引訪問元素很快,但是插入和刪除元素就很慢了,因為list是線性儲存,資料量大的時候,插入和刪除效率很低。

deque是為了高效實現插入和刪除操作的雙向列表,適合用於佇列和棧:

>>> from collections import deque
>>> q = deque(['a', 'b', 'c'])
>>> q.append('x')
>>> q.appendleft('y')
>>> q
deque(['y', 'a', 'b', 'c', 'x'])
複製程式碼

deque除了實現list的append()pop()外,還支援appendleft()popleft(),這樣就可以非常高效地往頭部新增或刪除元素。

defaultdict

>>> from collections import defaultdict
>>> dd = defaultdict(lambda: 'N/A')
>>> dd['key1'] = 'abc'
>>> dd['key1'] # key1存在
'abc'
>>> dd['key2'] # key2不存在,返回預設值
'N/A'
複製程式碼

注意預設值是呼叫函式返回的,而函式在建立defaultdict物件時傳入。

除了在Key不存在時返回預設值,defaultdict的其他行為跟dict是完全一樣的。

OrderedDict

使用dict時,Key是無序的。在對dict做迭代時,我們無法確定Key的順序。

如果要保持Key的順序,可以用OrderedDict

>>> from collections import OrderedDict
>>> d = dict([('a', 1), ('b', 2), ('c', 3)])
>>> d # dict的Key是無序的
{'a': 1, 'c': 3, 'b': 2}
>>> od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
>>> od # OrderedDict的Key是有序的
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
複製程式碼

注意,OrderedDict的Key會按照插入的順序排列,不是Key本身排序:

>>> od = OrderedDict()
>>> od['z'] = 1
>>> od['y'] = 2
>>> od['x'] = 3
>>> list(od.keys()) # 按照插入的Key的順序返回
['z', 'y', 'x']
複製程式碼

OrderedDict可以實現一個FIFO(先進先出)的dict,當容量超出限制時,先刪除最早新增的Key:

from collections import OrderedDict

class LastUpdatedOrderedDict(OrderedDict):

    def __init__(self, capacity):
        super(LastUpdatedOrderedDict, self).__init__()
        self._capacity = capacity

    def __setitem__(self, key, value):
        containsKey = 1 if key in self else 0
        if len(self) - containsKey >= self._capacity:
            last = self.popitem(last=False)
            print('remove:', last)
        if containsKey:
            del self[key]
            print('set:', (key, value))
        else:
            print('add:', (key, value))
        OrderedDict.__setitem__(self, key, value)
複製程式碼

Counter

Counter是一個簡單的計數器,例如,統計字元出現的個數:

>>> from collections import Counter
>>> c = Counter()
>>> for ch in 'programming':
...     c[ch] = c[ch] + 1
...
>>> c
Counter({'g': 2, 'm': 2, 'r': 2, 'a': 1, 'i': 1, 'o': 1, 'n': 1, 'p': 1})
複製程式碼

Counter實際上也是dict的一個子類,上面的結果可以看出,字元'g''m''r'各出現了兩次,其他字元各出現了一次。

base64

Base64是一種用64個字元來表示任意二進位制資料的方法。

Base64編碼會把3位元組的二進位制資料編碼為4位元組的文字資料,長度增加33%,好處是編碼後的文字資料可以在郵件正文、網頁等直接顯示。

如果要編碼的二進位制資料不是3的倍數,最後會剩下1個或2個位元組怎麼辦?Base64用\x00位元組在末尾補足後,再在編碼的末尾加上1個或2個=號,表示補了多少位元組,解碼的時候,會自動去掉。

>>> import base64
>>> base64.b64encode(b'binary\x00string')
b'YmluYXJ5AHN0cmluZw=='
>>> base64.b64decode(b'YmluYXJ5AHN0cmluZw==')
b'binary\x00string'
複製程式碼

struct

struct模組來解決bytes和其他二進位制資料型別的轉換,structpack函式把任意資料型別變成bytes

>>> import struct
>>> struct.pack('>I', 10240099)
b'\x00\x9c@c'
複製程式碼

pack的第一個引數是處理指令,'>I'的意思是:

>表示位元組順序是big-endian,也就是網路序,I表示4位元組無符號整數。'

hashlib

Python的hashlib提供了常見的摘要演算法,如MD5,SHA1等等。

我們以常見的摘要演算法MD5為例,計算出一個字串的MD5值:

import hashlib

md5 = hashlib.md5()
md5.update('how to use md5 in python hashlib?'.encode('utf-8'))
print(md5.hexdigest())
複製程式碼

計算結果如下:

d26a53750bc40b38b65a520292f69306
複製程式碼

還有很多內建模組也常使用,如:hmac,itertools,contextlib,urllib,XML,HTMLParser

常用第三方模組

除了內建的模組外,Python還有大量的第三方模組。

基本上,所有的第三方模組都會在PyPI - the Python Package Index上註冊,只要找到對應的模組名字,即可用pip安裝。

此外,在安裝第三方模組一節中,我們強烈推薦安裝Anaconda,安裝後,數十個常用的第三方模組就已經就緒,不用pip手動安裝。

Pillow

PIL:Python Imaging Library,已經是Python平臺事實上的影像處理標準庫了。PIL功能非常強大,但API卻非常簡單易用。

由於PIL僅支援到Python 2.7,加上年久失修,於是一群志願者在PIL的基礎上建立了相容的版本,名字叫Pillow,支援最新Python 3.x,又加入了許多新特性,因此,我們可以直接安裝使用Pillow。

安裝Pillow

如果安裝了Anaconda,Pillow就已經可用了。否則,需要在命令列下通過pip安裝:

$ pip install pillow
複製程式碼

如果遇到Permission denied安裝失敗,請加上sudo重試。

操作影像

來看看最常見的影像縮放操作,只需三四行程式碼:

from PIL import Image

# 開啟一個jpg影像檔案,注意是當前路徑:
im = Image.open('test.jpg')
# 獲得影像尺寸:
w, h = im.size
print('Original image size: %sx%s' % (w, h))
# 縮放到50%:
im.thumbnail((w//2, h//2))
print('Resize image to: %sx%s' % (w//2, h//2))
# 把縮放後的影像用jpeg格式儲存:
im.save('thumbnail.jpg', 'jpeg')
複製程式碼

其他功能如切片、旋轉、濾鏡、輸出文字、調色盤等一應俱全。

比如,模糊效果也只需幾行程式碼:

from PIL import Image, ImageFilter

# 開啟一個jpg影像檔案,注意是當前路徑:
im = Image.open('test.jpg')
# 應用模糊濾鏡:
im2 = im.filter(ImageFilter.BLUR)
im2.save('blur.jpg', 'jpeg')
複製程式碼

requests

用於訪問網路資源。

安裝requests

如果安裝了Anaconda,requests就已經可用了。否則,需要在命令列下通過pip安裝:

$ pip install requests
複製程式碼

如果遇到Permission denied安裝失敗,請加上sudo重試。

使用requests

要通過GET訪問一個頁面,只需要幾行程式碼:

>>> import requests
>>> r = requests.get('https://www.douban.com/') # 豆瓣首頁
>>> r.status_code
200
>>> r.text
r.text
'<!DOCTYPE HTML>\n<html>\n<head>\n<meta name="description" content="提供圖書、電影、音樂唱片的推薦、評論和...'
複製程式碼

對於帶引數的URL,傳入一個dict作為params引數:

>>> r = requests.get('https://www.douban.com/search', params={'q': 'python', 'cat': '1001'})
>>> r.url # 實際請求的URL
'https://www.douban.com/search?q=python&cat=1001'
複製程式碼

requests自動檢測編碼,可以使用encoding屬性檢視:

>>> r.encoding
'utf-8'
複製程式碼

無論響應是文字還是二進位制內容,我們都可以用content屬性獲得bytes物件:

>>> r.content
b'<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n...'
複製程式碼

requests的方便之處還在於,對於特定型別的響應,例如JSON,可以直接獲取:

>>> r = requests.get('https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20%3D%202151330&format=json')
>>> r.json()
{'query': {'count': 1, 'created': '2017-11-17T07:14:12Z', ...
複製程式碼

需要傳入HTTP Header時,我們傳入一個dict作為headers引數:

>>> r = requests.get('https://www.douban.com/', headers={'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit'})
>>> r.text
'<!DOCTYPE html>\n<html>\n<head>\n<meta charset="UTF-8">\n <title>豆瓣(手機版)</title>...'
複製程式碼

要傳送POST請求,只需要把get()方法變成post(),然後傳入data引數作為POST請求的資料:

>>> r = requests.post('https://accounts.douban.com/login', data={'form_email': 'abc@example.com', 'form_password': '123456'})
複製程式碼

requests預設使用application/x-www-form-urlencoded對POST資料編碼。如果要傳遞JSON資料,可以直接傳入json引數:

params = {'key': 'value'}
r = requests.post(url, json=params) # 內部自動序列化為JSON
複製程式碼

類似的,上傳檔案需要更復雜的編碼格式,但是requests把它簡化成files引數:

>>> upload_files = {'file': open('report.xls', 'rb')}
>>> r = requests.post(url, files=upload_files)
複製程式碼

在讀取檔案時,注意務必使用'rb'即二進位制模式讀取,這樣獲取的bytes長度才是檔案的長度。

post()方法替換為put()delete()等,就可以以PUT或DELETE方式請求資源。

除了能輕鬆獲取響應內容外,requests對獲取HTTP響應的其他資訊也非常簡單。例如,獲取響應頭:

>>> r.headers
{Content-Type': 'text/html; charset=utf-8', 'Transfer-Encoding': 'chunked', 'Content-Encoding': 'gzip', ...}
>>> r.headers['Content-Type']
'text/html; charset=utf-8'
複製程式碼

requests對Cookie做了特殊處理,使得我們不必解析Cookie就可以輕鬆獲取指定的Cookie:

>>> r.cookies['ts']
'example_cookie_12345'
複製程式碼

要在請求中傳入Cookie,只需準備一個dict傳入cookies引數:

>>> cs = {'token': '12345', 'status': 'working'}
>>> r = requests.get(url, cookies=cs)
複製程式碼

最後,要指定超時,傳入以秒為單位的timeout引數:

>>> r = requests.get(url, timeout=2.5) # 2.5秒後超時
複製程式碼

chardet

用來檢測編碼。

安裝chardet

如果安裝了Anaconda,chardet就已經可用了。否則,需要在命令列下通過pip安裝:

$ pip install chardet
複製程式碼

如果遇到Permission denied安裝失敗,請加上sudo重試。

使用chardet

當我們拿到一個bytes時,就可以對其檢測編碼。用chardet檢測編碼,只需要一行程式碼:

>>> chardet.detect(b'Hello, world!')
{'encoding': 'ascii', 'confidence': 1.0, 'language': ''}
複製程式碼

檢測出的編碼是ascii,注意到還有個confidence欄位,表示檢測的概率是1.0(即100%)。

我們來試試檢測GBK編碼的中文:

>>> data = '離離原上草,一歲一枯榮'.encode('gbk')
>>> chardet.detect(data)
{'encoding': 'GB2312', 'confidence': 0.7407407407407407, 'language': 'Chinese'}
複製程式碼

檢測的編碼是GB2312,注意到GBK是GB2312的超集,兩者是同一種編碼,檢測正確的概率是74%,language欄位指出的語言是'Chinese'

對UTF-8編碼進行檢測:

>>> data = '離離原上草,一歲一枯榮'.encode('utf-8')
>>> chardet.detect(data)
{'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}
複製程式碼

我們再試試對日文進行檢測:

>>> data = '最新の主要ニュース'.encode('euc-jp')
>>> chardet.detect(data)
{'encoding': 'EUC-JP', 'confidence': 0.99, 'language': 'Japanese'}
複製程式碼

可見,用chardet檢測編碼,使用簡單。獲取到編碼後,再轉換為str,就可以方便後續處理。

chardet支援檢測的編碼列表請參考官方文件Supported encodings

psutil

psutil = process and system utilities,它不僅可以通過一兩行程式碼實現系統監控,還可以跨平臺使用,支援Linux/UNIX/OSX/Windows等,是系統管理員和運維小夥伴不可或缺的必備模組。

安裝psutil

如果安裝了Anaconda,psutil就已經可用了。否則,需要在命令列下通過pip安裝:

$ pip install psutil
複製程式碼

如果遇到Permission denied安裝失敗,請加上sudo重試。

獲取CPU資訊

>>> import psutil
>>> psutil.cpu_count() # CPU邏輯數量
4
>>> psutil.cpu_count(logical=False) # CPU物理核心
2
# 2說明是雙核超執行緒, 4則是4核非超執行緒
複製程式碼

psutil還可以獲取使用者資訊、Windows服務等很多有用的系統資訊,具體請參考psutil的官網:github.com/giampaolo/p…

下一篇:Python學習之網路程式設計

相關文章