【Python】编程笔记11
文章目錄
- 常用內置模塊
- 一、datetime模塊
- 二、collections模塊
- 1、namedtuple() 函數
- 2、deque() 函數
- 3、defaultdict() 函數
- 4、OrderedDict() 函數
- 5、Counter() 函數
- 三、struct模塊
- 四、hashlib模塊
- 1、MD5
- 2、SHA1
- 3、應用:密碼存儲與校驗
- 五、itertools 模塊
- 1、“無限”迭代器
- 2、chain() 迭代器
- 3、groupby() 迭代器
- 六、XML
- 1、DOM vs. SAX
- 2、SAX
- 3、XML的生成
- 七、HTMLParser
- 八、urllib
- 1、get()
- 2、post()
- 3、Handler
- 九、常用第三方模塊
- 1、PIL(Python Imaging Library)——圖像處理
- 2、virtualenv
- 十、圖形界面
常用內置模塊
一、datetime模塊
datetime模塊:處理日期和時間的標準庫。
epoch time:1970 年 1 月 1 日 00:00:00 UTC+00:00 時區的時刻;
timestamp:當前時間相對于 epoch time 的秒數。
結果輸出
2018-12-25 09:39:32.382525 <class 'datetime.datetime'> 2019-01-01 00:00:00 1546301280.0 2019-01-01 08:08:00 2019-01-01 00:08:00 2019-01-01 18:28:30 Tue, Dec 25 09:39 2018-12-25 09:39:32.385442 2018-12-25 19:39:32.385442 2018-12-24 09:39:32.385442 2018-12-27 21:39:32.385442 2018-12-25 09:39:32.385442 2018-12-25 09:39:32.385442+10:00 2018-12-25 01:39:32.385513+00:00 2018-12-25 09:39:32.385513+08:00 2018-12-25 10:39:32.385513+09:00 2018-12-25 10:39:32.385513+09:00 Pass二、collections模塊
集合模塊,提供集合類
1、namedtuple() 函數
tuple的子類,用于創建自定義的 tuple 對象,并規定 tuple 元素的個數,可用屬性來引用 tuple 的某個元素。
from collections import namedtuple # namedtuple('名稱', [屬性list]) ## 定義 Point Point = namedtuple('Point',['x', 'y']) p = Point(1, 2) print(p.x) print(p.y) ## 定義 Circle Circle = namedtuple('Circle', ['x','y','r']) c = Circle(3,5,9) print(c.x, c.y, c.r) print(isinstance(p, Point)) print(isinstance(p, tuple))結果輸出
1 2 3 5 9 True True2、deque() 函數
可高效實現插入和刪除操作的雙向列表,適用于隊列和棧。
除了實現 list 的 append()和 pop()外,還支持 appendleft() 和 popleft() ==》非常高效地往頭部添加或刪除元素。
from collections import deque q = deque(['a', 'b', 'c']) q.append('x') q.appendleft('y') print(q)結果輸出
deque(['y', 'a', 'b', 'c', 'x'])3、defaultdict() 函數
defaultdict()函數:當 Key 不存在時,返回一個默認值。其余與dict一樣。
注意:默認值是調用函數返回的,而函數在創建 defaultdict 對象時傳入。
from collections import defaultdict dd = defaultdict(lambda : 'N/A') dd['key1'] = 'abc' print(dd['key1']) print(dd['key2'])結果輸出
abc N/A4、OrderedDict() 函數
OrderedDict 的 Key 會按照插入的順序排列,不是 Key 本身排序。
from collections import OrderedDict d = dict([('a',1),('c',3),('b',2)]) print(d) od = OrderedDict([('a',1),('c',3),('b',2)]) print(od) od1 = OrderedDict() od1['z'] = 1 od1['y'] = 2 od1['x'] = 3 print(list(od1.keys()))結果輸出
{'a': 1, 'c': 3, 'b': 2} OrderedDict([('a', 1), ('c', 3), ('b', 2)]) ['z', 'y', 'x']使用 OrderedDict 實現一個 FIFO(先進先出)的 dict,當容量超出限制時,先刪除最早添加的 Key。
from collections import OrderedDictclass LastUpdatedOrderedDict(OrderedDict):def __init__(self, capacity):super(LastUpdatedOrderedDict, self).__init__()self._capacity = capacitydef __setitem__(self, key, value):containsKey = 1 if key in self else 0if 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)5、Counter() 函數
作用:計數器
## 統計字符出現的個數 from collections import Counter c = Counter() for ch in 'programming':c[ch] = c[ch] + 1 print(c)結果輸出
Counter({'r': 2, 'g': 2, 'm': 2, 'p': 1, 'o': 1, 'a': 1, 'i': 1, 'n': 1})三、struct模塊
作用:解決 bytes 和其他二進制數據類型的轉換。
import struct print(struct.pack('>I', 10240099)) # b'\x00\x9c@c' # >IH 的說明,后面的 bytes 依次變為 I:4 字節無符號整數和 # H: 2 字節無符號整數。 print(struct.unpack('>IH', b'\xf0\xf0\xf0\xf0\x80\x80'))參數:pack第一個參數是處理指令。
‘>I’表示:>表示字節順序是 big-endian,也就是網絡序, I 表示 4 字節無符號整數。后面的參數個數要和處理指令一致。
四、hashlib模塊
提供常見的摘要算法(哈希算法、散列算法),eg:MD5、SHA1等。修改一小點,結果完全不同。單向函數。
通過一個函數將任意長度的數據轉換為一個長度固定的數據串(通常用16進制的字符串表示)。
1、MD5
MD5 是最常見的摘要算法,速度很快,生成結果是固定的 128 bit 字節,通常用一個 32 位的 16 進制字符串表示。
import hashlib md5 = hashlib.md5() md5.update('how to use md5 in python hashlib?'.encode('utf-8')) print(md5.hexdigest()) ## 多次調用 update() md5 = hashlib.md5() md5.update('how to use md5 in '.encode('utf-8')) md5.update('python hashlib?'.encode('utf-8')) print(md5.hexdigest()) ## 改動一個字母 md5.update('how to use md5 in python hashlid?'.encode('utf-8')) print(md5.hexdigest())## 結果輸出 # d26a53750bc40b38b65a520292f69306 # d26a53750bc40b38b65a520292f69306 # 9ac2e3728468630f3d1aecc058e78dff2、SHA1
結果是 160 bit 字節,通常用一個 40 位的 16 進制字符串表示。
sha1 = hashlib.sha1() sha1.update('how to use md5 in '.encode('utf-8')) sha1.update('python hashlib?'.encode('utf-8')) print(sha1.hexdigest())## 結果輸出 # b752d34ce353e2916e943dc92501021c8f6bca8c注意:可能出現兩個不同的數據通過某個摘要算法得到相同的摘要,只是非常困難。
3、應用:密碼存儲與校驗
摘要算法不是加密算法,不能用于加密(因為無法通過摘要反推明文),只能用于防篡改或者驗證用戶口令。
import hashlib db = { 'michael': 'e10adc3949ba59abbe56e057f20f883e', 'bob': '878ef96e86145580c38c87f0410ad153', 'alice': '99b1c2188db85afee403b1536010c2c9' } def login(user, password):ps_md5 = hashlib.md5()ps_md5.update(password.encode('utf-8'))if ps_md5.hexdigest() == db[user]:return Trueelse:return False print(login('bob','abc999'))更安全方法:通過對原始口令加一個復雜字符串來實現,俗稱“加鹽”
eg:添加固定字符串、將不變的用戶名作為salt的一部分。
根據用戶輸入的登錄名和口令模擬用戶注冊,計算更安全的 MD5
import hashlib, randomdef get_md5(s):return hashlib.md5(s.encode('utf-8')).hexdigest()class User(object):def __init__(self, username, password):self.username = usernameself.salt = ''.join([chr(random.randint(48, 122)) for i in range(20)])self.password = get_md5(password + self.salt) db = {'michael': User('michael', '123456'),'bob': User('bob', 'abc999'),'alice': User('alice', 'alice2008')}def login(username, password):user = db[username]return user.password == get_md5(password + user.salt) assert login('michael', '123456') assert login('bob', 'abc999') assert login('alice', 'alice2008') assert not login('michael', '1234567') assert not login('bob', '123456') assert not login('alice', 'Alice2008') print('ok') ## ok五、itertools 模塊
itertools 模塊提供用于迭代對象的函數。返回值為 Iterator,需要用 for 循環迭代獲取元素。
1、“無限”迭代器
- itertools.count(5):從5開始的自然數序列。
==》5,6,7,8,9,10,11,12,13… - itertools.cycle(‘ABC’):將一個序列無限重復下去。
==》‘A’,‘B’,‘C’,‘A’,‘B’,‘C’,‘A’,‘B’,‘C’… - itertools.repeat():將一個元素無限重復下去,第二個參數可以限定重復次數。
- 注意:無限序列只有在 for 迭代時才會無限迭代下去,但是通常通過 takewhile() 等函數根據條件判斷來截取一個有限的序列。
結果輸出
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]2、chain() 迭代器
可以將一組迭代對象串聯起來,形成一個更大的迭代器
for c in itertools.chain('ABC', 'XYZ'):print(c) # 迭代效果: 'A' 'B' 'C' 'X' 'Y' 'Z'3、groupby() 迭代器
將相鄰的重復元素挑出來放在一起。
for key, group in itertools.groupby('AAAaaaaaBBBbcCCAAa'):print(key, list(group)) print('---------------------------------------------')## 忽略大小寫 for key, group in itertools.groupby('AAAaaaaaBBBbcCCAAa', lambda c: c.upper()):print(key, list(group))結果輸出
A ['A', 'A', 'A'] a ['a', 'a', 'a', 'a', 'a'] B ['B', 'B', 'B'] b ['b'] c ['c'] C ['C', 'C'] A ['A', 'A'] a ['a'] --------------------------------------------- A ['A', 'A', 'A', 'a', 'a', 'a', 'a', 'a'] B ['B', 'B', 'B', 'b'] C ['c', 'C', 'C'] A ['A', 'A', 'a']六、XML
1、DOM vs. SAX
兩種操作XML方法:DOM 和 SAX。
- DOM 會把整個 XML 讀入內存,解析為樹 ==》占用內存大,解析慢,優點是可以任意遍歷樹的節點。
- SAX 是流模式,邊讀邊解析,占用內存小,解析快,缺點是我們需要自
己處理事件 - 正常情況下:優先考慮SAX(DOM太占內存)
2、SAX
關鍵函數:start_element 、end_element 和 char_data
from xml.parsers.expat import ParserCreateclass DefaultSaxHandler(object):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)xml = r'''<?xml version="1.0"?> <ol><li><a herf="/python">Python</a></li><li><a herf="/ruby">Ruby</a></li> </ol> ''' handler = DefaultSaxHandler() parser = ParserCreate() parser.StartElementHandler = handler.start_element parser.EndElementHandler = handler.end_element parser.CharacterDataHandler = handler.char_data parser.Parse(xml)結果輸出
sax: start_element: ol, attrs: {} sax: char_data: sax: char_data: sax: start_element: li, attrs: {} sax: start_element: a, attrs: {'herf': '/python'} sax: char_data: Python sax: end_element: a sax: end_element: li sax: char_data: sax: char_data: sax: start_element: li, attrs: {} sax: start_element: a, attrs: {'herf': '/ruby'} sax: char_data: Ruby sax: end_element: a sax: end_element: li sax: char_data: sax: end_element: ol3、XML的生成
最簡單的方法:拼接字符串
L = [] L.append(r'<?xml version="1.0"?>') L.append(r'<root>')七、HTMLParser
解析HTML(HTML是XML的子集,但HTML的語法沒有XML那么嚴格)
from html.parser import HTMLParser from html.entities import name2codepointclass MyHTMLParser(HTMLParser):def handle_starttag(self, tag, attrs):print('<%s>' % tag)def handle_endtag(self, tag):print('</%s>' % tag)def handle_startendtag(self, tag, attrs):print('<%s/>' % tag)def handle_data(self, data):print(data)def handle_comment(self, data):print('<!--', data, '-->')def handle_entityref(self, name):print('&%s;' % name)def handle_charref(self, name):print('&#%s;' % name)parser = MyHTMLParser() parser.feed('''<html> <head></head> <body> <!-- test html parser --> <p>Some <a href=\"#\">html</a> HTML tutorial...<br>END</p> </body></html>''')- feed() 方法可以多次調用,可以分部分傳入數據。
八、urllib
提供一系列用于操作 URL 的功能。
1、get()
urllib.request 模塊可抓取 URL 內容:發送get請求到指定的頁面,然后返回 HTTP 的響應。
from urllib import request# url = 'https://api.douban.com/v2/book/2129650' url = 'http://www.douban.com/' req = request.Request(url = url) # 添加 HTTP 頭,可以偽裝成瀏覽器 req.add_header('User-Agent','Mozilla/6.0 (iPhone; CPU iPhones OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25') with request.urlopen(req) as f:data = f.read()print('Status:', f.status, f.reason)for k, v in f.getheaders():print('%s: %s' % (k, v))print('Data:', data.decode('utf-8'))2、post()
以POST發送一個請求,只需把參數 data 以 bytes 形式傳入。
from urllib import request, parseprint('Login to weibo.cn...') email = input('Email:') passwd = input('Password:') login_data = parse.urlencode([('username', email),('password', passwd),('entry', 'mweibo'),('client_id',''),('savestate', '1'),('ec', ''),('pagerefer','https://passport.weibo.cn/signin/welcome?entry=nweibo&r=http%3A%2F%2Fm.weibo.cn%2F') ]) url = 'https://passport.weibo.cn/sso/login' req = request.Request(url) req.add_header('Origin', 'https://passport.weibo.cn') req.add_header('User-Agent','Mozilla/6.0 (iPhone; CPU iPhones OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25') req.add_header('Referer','https://passport.weibo.cn/signin/login?entry=mweibo&res=wel&wm=3349&r=http%3A%2F%2Fm.weibo.cn%2F')with request.urlopen(req, data=login_data.encode('utf-8')) as f:print('Status:', f.status, f.reason)for k, v in f.getheaders():print('%s: %s' % (k, v))print('Data:', f.read().decode('utf-8'))3、Handler
若需要通過一個 Proxy 來訪問網站,則利用 ProxyHandler 來處理。
九、常用第三方模塊
1、PIL(Python Imaging Library)——圖像處理
2、virtualenv
為應用創建一套 Python 運行環境
十、圖形界面
第三方庫:Tk、wxWidgets、Qt、GTK
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的【Python】编程笔记11的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Python】编程笔记10
- 下一篇: 《笨办法学python》(《learn