github 上有哪些非常優秀的 Python 項目可供學習?
https://github.com/vinta/awesome-python
猶豫再三還是厚著臉皮推薦一下自己的項目
GitHub - hubo1016/namedstruct: Define complicated C/C++ structs in Python with variable length arrays, header/extend relations, extensible structures in one time, parse/rebuild them with a single line of code
有的時候需要用Python解析C/C++中的二進位結構體,比如讀取二進位文件、調用Linux的系統函數、解析裸的乙太網數據包等。系統的struct庫是個比較方便的選擇,但是用struct庫我們必須這麼寫:import struct
myint, myshort, mybyte1, mybyte2 = struct.unpack(&>IHBB, mydata)
這個代碼很難維護,得記住不同數據類型用什麼字母代表,得仔細對齊兩邊的數據類型和欄位名,如過有嵌套的結構那又不行了。而且很醜。
用namedstruct應該怎麼寫呢?from namedstruct import *
mystruct = nstruct((uint32, myint),
(uint16, myshort),
(uint8, mybyte1),
(uint8, mybyte2),
name = "mystruct",
padding = 1)
myobj = mystruct.parse(mydata)
# 反過來,構造也是可以的
myobj2 = mystruct(myint = 2, myshort = 3, mybyte2 = 4)
mydata2 = myobj2._tobytes()
這個定義跟C/C++中的struct定義的結構很像,很多時候把.h複製出來,照著改一下,馬上就有了一個可以用的Python結構體對象。
僅僅是這樣大概沒什麼好稀奇的,這個庫最重要的功能是支持變長的結構體。常見的有兩種,一種是可變數組:mystruct_array = nstruct((uint16, length),
(mystruct[0], array),
name = "mystruct_array",
padding = 1,
size = lambda x: x.length,
prepack = packsize(length))
myarray = mystruct_array(array = [mystruct(myint = 2), mystruct(myint = 3)])
# 轉為二進位串時,會自動調用prepack,將結構體的大小存進length欄位
myarraydata = myarray._tobytes()
# 解析時,會自動調用size,從length欄位獲取結構體的大小
myarray2 = mystruct_array.parse(myarraydata)
另一種是struct的擴展,一類結構體有共同的頭部,根據頭部的類型欄位判斷結構體具體屬於何種類型,不同類型結構體後面的欄位不同,定義的邏輯與C++的類繼承有些類似:
mytypeenum = enum(mytypeenum, globals(), uint16,
IPV4 = 4,
IPV6 = 6)
myheader = nstruct((mytypeenum, type),
(uint16, length),
name = "myheader",
padding = 1,
size = lambda x: x.length,
prepack = packsize(length))
mytype1 = nstruct((uint32, ip_src),
(uint32, ip_dst),
name = "mytype1",
padding = 1,
base = myheader,
criteria = lambda x: x.type == IPV4,
init = packvalue(IPV4, type))
mytype2 = nstruct((uint8[16], ip6_src),
(uint8[16], ip6_dst),
name = "mytype2",
padding = 1,
base = myheader,
criteria = lambda x: x.type == IPV6,
init = packvalue(IPV6, type))
# 可以用基類來定義數組,數組中可以混合存儲派生類型
myheader_array = nstruct((uint16, length),
(myheader[0], array),
name = "myheader_array",
padding = 1,
size = lambda x: x.length,
prepack = packsize(length))
arrayobj = myheader_array(array = [mytype1(ip_src = 12, ip_dst = 24),
mytype2(ip6_src = [0] * 11 + [1],
ip6_dst = [0] * 12)])
這個庫能夠定義多複雜的結構體呢?在misc目錄當中,我用這個庫的功能定義了常見的網路包的格式,和Openflow協議的全部結構體。
namedstruct/packetdump.py at master · hubo1016/namedstruct · GitHub
這個腳本用相應的定義實現了一個類似於tcpdump的抓包工具,不算ethernet的定義只有253行,ethernet裡面的定義也只有1000行,執行方法是首先安裝namedstruct庫:pip install nstruct然後將packetdump.py和ethernet.py兩個文件複製到本地,然後(必須在Linux操作系統上)python packetdump.py proto=IPPROTO_ICMP玩一玩這個packetdump也是挺有意思的,如過有興趣可以再看看ethernet的定義和namedstruct的實現。代碼寫的挺亂的,不知道適不適合學習……
做數據分析:pandas,提供了類似R的dataframe的一種數據結構。文檔很詳細。數據可視化,繪圖:matplotlib,跟matlab很相似。機器學習演算法:scikit-learn。
不過源碼可不好讀。
http://www.zhihu.com/question/25697796
推薦閱讀:
※開發者對 npm 公司不滿,unpublish 了自己的所有模塊
※如何看待 Swift 開源一周 star 數就超過 Rust 和 Go?
※原來開源根本不是我想像的那樣
※GitHub 上有哪些安全相關的 Python 項目值得一讀?