1. 程式人生 > >python的電池——內建模組

python的電池——內建模組

本部落格只為彙總內建模組的基本用法,方便查閱。

目錄

datetime:        處理時間和日期

collections:     集合模組

base64:       64個字元表示二進位制資料

Struct:            操作位元組的模組

hashlib:          摘要演算法模組

hmac:             標準加鹽演算法模組

itertools:         迭代工具模組

contextlib:      上下文模組

urllib:              提供http請求的模組

xml:                解析xml格式資料的模組

HTMLParser: 解析HTML的模組


 

datetime: 處理時間和日期

  • 匯入 from datetime import datetime, timedelta, timezone
  • datetime.now() 獲取當前時間,沒有時區資訊tzinfo=None,表示本地時間
  • datetime(2018,12,23,10,24) 建立指定本地時間
  • datetime物件.timestamp() 日期時間物件轉換成timestamp, timestamp是相對UTF+0的,本地時間就是自己電腦所在時區去轉,設定了tzinfo資訊的,就按照設定的時區去轉。理論上來說,世界上所有電腦在同一時刻,得到的本地時間會因時區有差異,但是timestamp都是相同的。
  • datetime.fromtimestamp(111111.0) 把timestamp轉為本地時間
  • datetime.utcfromtimestamp(1111111.0) 把timestamp轉為UTF+0時區的時間
  • datetime.strptime('2018-12-23 10:37:59', '%Y-%m-%d %H:%M:%S') 把字串按照指定格式,轉為本地時間 str parse time
  • datetime物件.strftime('%a, %b %d %H:%M') 把本地時間按照指定格式,轉為字串 str from time
  • datetime物件 + timedelta(days=2, hours=12) 時間的加減,需要用timedelta 就像Java的Calendar類做的一樣
  • datetime物件.replace(tzinfo=timezone(timedelta(hours=10))) 設定時區資訊 需要用到timezone, 而timezone需要用到tiemdelta. 另外 tzinfo關鍵字引數就是timezone information時區資訊的意思
  • datetime物件.astimezone(timezone(timedelta(hours=8))) 根據設定的時區資訊,修改datetime物件的值。也就是時間在不同時區的轉換。

collections: 集合模組

  • namedtuple 給tuple命名並且可以依靠屬性訪問
from collections import namedtuple
Point = namedtuple('point', ['x', 'y'])
p = Point(1,2)
print(p)
print(p.x, p.y)
  • deque 雙向連結串列,支援頭尾高效插入刪除
from collections import deque
q = deque(['a', 'b', 'c'])  #左右頭尾插入刪除
q.append('d')
q.appendleft('A')
q.pop()
q.popleft()
  • OrderedDict 按插入順序排序的dict, 還可以按棧或佇列的方式刪除
from collections import OrderedDict
od = OrderedDict([('a',1), ('d',2), ('c',3)]) #按插入順序排序的dict
od['b'] = 4             #新增
od.pop('a')             #刪除
od.popitem(last=False)            #last=False採用FIFO佇列彈出,last=True採用LIFO棧彈出
  • ChainMap 把幾個dict串聯起來,按左高右低的優先順序查詢
from collections import ChainMap
da = {'a':1, 'b':2}
db = {'c':3, 'a':2}
cm = ChainMap(da, db) #優先查da,沒有再查db
print(cm['a'], cm['c'])
  • Counter 計數器,很方便的完成計數,不用自己去看到底在不在裡面,封裝好了
from collections import Counter
c = Counter()   #計數器 是一個dict的子類
for ch in 'I love python':
    c[ch] = c[ch] + 1           #這一句搞定計數
print(c)

base64:64個字元表示二進位制資料

64個字元可以表示6bit的資料,所以把二進位制資料每6bit換成一個字元即可。這樣3個位元組的二進位制資料經過base64編碼後,變成4個位元組的可顯示字元資料。長度不是3的倍數就用\x00補齊,然後編碼末尾用=指示補了多少個位元組

  • base64.b64encode(b'abcde') 把二進位制資料編碼成base64資料
  • base64.b64decode(b'YWJjZGU=') 把base64資料解碼成二進位制資料
  • base64.urlsafe_b64encode(b'abcde') 把二進位制資料編碼成url安全的base64資料,也就是+和/ 換成 -和_
  • base64.urlsafe_b64decode(b'YWJjZGU=')  把url安全的base64資料解碼成二進位制資料

Struct: 操作位元組的模組

封裝了對python資料型別的位元組操作,在對位元組流效能要求不高的時候,可以使用。型別表示見官方文件

  • struct.pack('>IH', 1234567, 22)  >大端序(網路序,高位在前,符合人的習慣) I表示4位元組整數 H表示2位元組整數。表示把這兩個數字按照前面指定的方式提取出位元組表示 b'\x00\x12\xd6\x87\x00\x16'
  • struct.unpack('>IH', b'\x00\x12\xd6\x87\x00\x16') 按照指定的方式,從位元組流中提取出資料。(1234567, 22)

hashlib: 摘要演算法模組

把任意長度的資料轉換成一個固定長度的資料。屬於不可逆演算法,所以可以用來做加密工作。

  • update() 向摘要演算法提供需要摘要的原始資料
  • hexdigest() 計算並返回摘要

MD5:

import hashlib
md = hashlib.md5()             #找到md5物件
md.update('今天你會不會嫁給我'.encode('utf-8'))     #更新md5值
md.update('abcde'.encode('utf-8')) #重複的呼叫等價於連線所有引數的單個呼叫:m.update(a);m.update(b)等價於m.update(a+b)
md.hexdigest()                  #獲取md5計算結果 128bit 32個16進位制數

SHA1:用法和MD5完全一樣

import hashlib
sha = hashlib.sha1()
sha.update('今天你會不會嫁給我'.encode('utf-8'))
sha.update('abcde'.encode('utf-8'))
sha.hexdigest()                 #獲取sha1摘要結果 160bit 40個16進位制數

hmac: 標準加鹽演算法模組

一般為了防止密碼被破解,會用password + salt 然後再hash。這麼做太簡陋了,hmac就是把這個簡單的加法變複雜的一個模組。

import hmac
h = hmac.new(b'secret', b'hello, world', digestmod='MD5') #第一個引數就是所謂的salt或者key 第二個是要加密的資料
h.update(b' you')
h.hexdigest()

itertools: 迭代工具模組

  • 匯入 import itertools
  • itertools.count(-1, 2) 返回從-1開始每次+2的Iterator物件,因為是無限迭代,所以就是一個generator。
  • itertools.cycle('AB') 返回無限重複的'A' 'B'
  • itertools.repeat('ABC', 3) 返回重複3次的'ABC' iterator
  • itertools.takewhile(lambda x: x <= 10, natural) natural可以是上面的無限迭代生成器, takewhile指定停止條件
  • itertool.chain(i1, i2) 把i1, i2兩個iterator 連線起來,返回一個更大的itrator 
  • itertools.groupby('AaaBBbcCAAa', lambda c: c.upper()) 按相鄰元素是否一樣分組,分組前可做對映

contextlib: 上下文模組

這個模組主要是管理資源的,一個物件建立的時候獲取資源,銷燬的時候釋放資源。本來是通過魔法方法__enter__和__exit__配合with管理的。contextlib模組提供了裝飾器來支援更加簡便的管理。

  • @contextmanager 即使不實現__enter__和__exit__也可以通過with去自動釋放
from contextlib import contextmanager
class Person(object):

    def __init__(self, name):
        self.name = name
        print('init')

    def me(self):
        print('my name is %s...' % self.name)

@contextmanager #和用魔法方法實現不同,這裡Begin會在初始化之前執行, 不過不重要,因為with主要是釋放資源嘛
def create_person(name):
    print('Begin')
    yield Person(name)
    print('End')

with create_person('小明') as p:
    p.me()

Output:
Begin
init
my name is 小明...
End
  • closing() 讓沒有實現上下文的物件,但卻實現了close()方法的物件也能用with自動釋放
@contextmanager
def closing(thing):
    try:
        yield thing    #就和我們自己寫的create_Person一模一樣 用的使用需要import closing
    finally:
        thing.close()

urllib: 提供http請求的模組

  • 匯入 from urllib import request
  • request.urlopen('https://www.baidu.com') 傳送http請求到指定url,然後返回該請求的返回
from urllib import request

with request.urlopen('https://www.baidu.com') as f:
    data = f.read()            #注意這裡data是二進位制編碼的utf-8資料
    print('Status:', f.status, f.reason)
    for k, v in f.getheaders():
        print('%s: %s' % (k, v))
    print('Data:', data.decode('utf-8'))    #直接顯示需要解碼,如果是json資料還需要loads
  • request.add_header(...)  新增http請求頭資訊 我暫時沒用過 來把程式的請求偽裝的像是真的通過人去點的一樣

xml: 解析xml格式資料的模組

比解析json資料複雜太多了

xml = r'''<?xml version="1.0"?>
<ol>
    <li><a href="/python">Python</a></li>
    <li><a href="/ruby">Ruby</a></li>
</ol>
'''

from xml.parsers.expat import ParserCreate

def start_element(self, name, attrs):
    print('sax:start_element: %s, attrs: %s' % (name, str(attrs)))

def end_element(self, name):
    print('sax:end_element: %s' % name)

def char_data(self, text):
    print('sax:char_data: %s' % text)

parser = ParserCreate()
parser.StartElementHandler = start_element
parser.EndElementHandler = end_element
parser.CharacterDataHandler = char_data
parser.Parse(xml)

HTMLParser: 解析HTML的模組

官方文件連線

from html.parser import HTMLParser

class MyHTMLParser(HTMLParser):

    def handle_starttag(self, tag, attrs):
        print('<%s %s>' % (tag, attrs))

    def handle_endtag(self, tag):
        print('</%s>' % tag)

    def handle_startendtag(self, tag, attrs):   #因為html沒有xml嚴格 所以要解析的東西就多,就會有這種開頭結尾在一起的標籤
        print('<%s %s/>' % (tag, attrs))

    def handle_data(self, data):
        print(data)

    def handle_comment(self, data):     #註釋
        print('<!--', data, '-->')

    def handle_entityref(self, name):   #字元實體 如 &nbsp   只有charref為False時,才會呼叫
        print('&%s;' % name)

    def handle_charref(self, name):     #數字實體 如 &#1234
        print('&#%s;' % name)

parser = MyHTMLParser(convert_charrefs=False)
parser.feed('''<html>
<head></head>
<body>
<!-- test html parser -->
    <p>Some <a href=\"#\">html</a> HTML&nbsp;&#2555;tutorial...<br>END</p>
</body></html>''')