初學 Python,有哪些 Pythonic 的源碼推薦閱讀?

初學Python,要想讓自己的Python代碼更加Pythonic,所以想找一些Pythonic的代碼來看看!


謝邀。看到邀請已經很久了,一直沒敢回答,主要是我自己沒有讀過多少模塊的源碼,因為我一直認為讀源碼是一種比較「低效」的學習方法。我用 yolk -al 看了一下安裝的模塊,發現居然也沒有幾個算是「讀過」的。web.py 的讀過一點,它的介面很 pythonic,但這貨的實現應該算不上是非常 pythonic 的代碼。

如果一定要推薦一些 python 的源碼去讀,我的建議是標準庫里關於網路的代碼。從 SocketServer 開始,補上 socket 模塊的知識,熟悉 TCP/UDP 編程,然後了解 Mixin 機制的最佳示例 SocketServer.{ForkingMixIn|ThreadingMixIn},借這個機會了解 thread/threading 模塊,這時會對並發量提出新的要求,就可以讀 select 模塊,開始對 select/{epoll|kqueue} 有深刻理解,搞懂以後就可以接觸一下非同步框架 asyncore 和 asynchat。這時開始出現分岔。如果是做 game 等以 TCP/UDP 協議為基礎的應用,可以去讀 greenlet 和 gevent,如果是做 web,則走下一條路。

做 web,讀 BaseHTTPServer、SimpleHTTPServer 和 CGIHTTPServer,讀 cgi/cgitb,自己隨意寫框架,讀cookielib,讀 wsgiref,這時候自己寫一個簡便的 web framework 就 so easy 了,老闆再也不擔心你寫 web 了,選擇 flask/web.py/django/pyramid 都心中有數了。因為走的是 web 的路,所以難免要調用一下別人的 api,搞懂一下 httplib/urllib/urllib/urlparse。

最後,上述提到的標準庫,我大多讀過。


  • 大神 Armin Ronacher的博客 Blog | Armin Ronacher"s Thoughts and Writings , 有很多代碼的經驗和技巧分享, 他寫的一些庫如 flask, werkzeug 可讀性都很好
  • kennethreitz 寫的一系列 python lib for human, 如 requests, tablib 等
  • gunicorn 的作者benoitc 寫的python代碼基本都比較 pythonic https://github.com/benoitc , 個人很喜歡讀他的代碼
  • 不超過500 行代碼的各種項目(以 Python 為主,不全是 Python) GitHub - aosabook/500lines: 500 Lines or Less
  • 至於那些 web 框架如 pyramid, django 之類不是很推薦初學者去閱讀,過於龐大且用了一些高級trick等讓初學者難以理解

這個題目本身就有點困難. 因為好的源碼都帶有對python更深入的理解,熟悉各種python標準庫模塊使用和以及各種trick,豈是初學者那麼好懂的?直接標準庫模塊的就算了吧....


我覺得好的代碼要有:

1. pythonic的用法

2. 盡量少的複雜的邏輯


我在我的專欄「Python之美 - 知乎專欄」中寫過一篇文章 教你閱讀Python開源項目代碼 - Python之美 - 知乎專欄。其中介紹了初學者和有一定經驗者可以閱讀的一些開源項目,最後也介紹了閱讀別人代碼的一些經驗,在這裡再發一下,順便加點其他的推薦:


閱讀Python開源項目代碼主要有如下三個原因:

1. 在工作過程中遇到一些問題,Google和StackOverFlow等網站找不到解決辦法,只能去翻源碼。

2. 對某些項目或者方向非常感興趣,希望深入。

3. 學習遇到瓶頸需要汲取開源項目的經驗和用法來做提高。

沒有目的的閱讀開源項目就是耍流氓。浪費了時間,但是能學到的東西也很少。怎麼樣根據自身情況去閱讀呢?

1. 和興趣以及工作契合。舉個例子,工作中沒有機會用到Celery又不是想自己造個輪子,讀它的源碼做什麼?所以要從平時能接觸到的那些項目中選取。比如我,我肯定不去看Django的代碼,因為日常工作基本遇不到,遇到了現翻就好了。

2. 一個方向只看一兩個典型的就可以了。比如Web框架,我只看過Bottle和Flask的源碼(其實之前也看過Django的,只是淺嘗輒止),而且看Bottle已經是好幾年前的事情了。並不是堆的多了更好,有時候反而選擇太多會懵。

3. 不同技術階段的選擇代碼量、複雜度不一樣的項目,下面會具體推薦。

4. 清楚自己看代碼的目的。就是你看代碼是想了解人家怎麼設計、調試BUG、還是只是想學習正確的編程用法呢?其實沒有必要細摳每個代碼細節,有時候當黑盒看,知道輸入輸出就可以了。


我個人的喜好


和工作中看別人代碼差不多,基本每個人、每個項目、每個團隊都有自己寫代碼的風格,比如變數命名風格、某些語言特性使用方式、代碼規範要求、目錄風格等,其實開源項目的作者也是一樣。看代碼,如看人(團隊)。 首先介紹下我的喜好(排名分先後):

1. kennethreitz。requests和python-guide作者。他還有一個非常勵志的故事,有興趣的可以看 誰說程序員不是潛力股?

2. mitsuhiko。flask、Jinja2、werkzeug和flask-sqlalchemy作者。

3. sigmavirus24。flake8、pycodestyle(原pep8)、requests、urllib3等項目的主要貢獻者和維護者。

4. ask。Celery及相關依賴的作者。

5. ajdavis。mongo-python-driver(pymongo)、tornado等項目的主要貢獻者。

6. bitprophet。fabric、paramiko(Python的ssh庫)作者。

前2個是公認的Python領域代碼寫的最好的、最有創意的工程師。


初學者推薦閱讀項目


初學者可以先閱讀一些代碼量比較少的,最好是單文件的項目:

1. GitHub - kennethreitz/pip-pop: Tools for managing requirements files.

2. GitHub - kennethreitz/envoy: Python Subprocesses for Humans?.

3. GitHub - kennethreitz/records: SQL for Humans?

4. GitHub - mitsuhiko/pluginbase: A simple but flexible plugin system for Python.

5. GitHub - mitsuhiko/pipsi: pip script installer

6. GitHub - mitsuhiko/unp: Unpacks things.

7. GitHub - chrisallenlane/cheat

8. GitHub - jek/blinker: A fast Python in-process signal/event dispatching system.

9. GitHub - mitsuhiko/platter: A useful helper for wheel deployments.

10. GitHub - kennethreitz/tablib: Python Module for Tabular Datasets in XLS, CSV, JSON, YAML, amp;amp;amp;c.

看代碼主要是了解別人寫代碼的方式,語法實踐這些內容。看完之後,你可以針對這些項目能解決的問題自己寫個項目,寫完之後和上述項目去對比一下,看看哪些方面做的不好。


進階閱讀項目


進階的時候就要閱讀一些相對複雜的項目,它們能幫助你提升Python編程技巧:

1. faif/python-patterns。使用Python實現一些設計模式的例子。

2. pallets/werkzeug。flask的WSGI工具集。其中包含了實現非常好的LocalProxy、cached_property、import_string、find_modules、TypeConversionDict等。

3. bottlepy/bottle。閱讀一個Web框架對Web開發就會有更深刻的理解,flask太大,bottle就4k多行,當然如果你有毅力和興趣直接看flask是最好了的。

4. msiemens/tinydb。了解用Python實現資料庫。

5. coleifer/peewee。了解ORM的實現。

6. pallets/click。click已經內置於在flask 0.11里,提供命令行功能,值得閱讀。

7. mitsuhiko/flask-sqlalchemy。了解一個flask插件是怎麼實現的。

GitHub - gregmalcolm/python_koans: Python Koans 是個不錯的練手項目,我還曾經給它貢獻過代碼。在你學會Python以後可以拿它練手,一步一步的完成所有待解決的問題。


除此之外Web開發者可以閱讀一些相關的項目:

1. runscope/httpbin。使用flask,網站是httpbin(1): HTTP Client Testing Service。

2. jahaja/psdash。使用flask和psutils的獲取Linux系統信息的面板應用。

3. pallets/flask-website。 flask官方網站應用。

4. pypa/warehouse。如果你使用pyramid,這個新版的PYPI網站,可以幫助你理解很多。

當然,2個學習flask重要的資源必須爆一爆:

1. GitHub - realpython/discover-flask: Full Stack Web Development with Flask。

2. The Flask Mega-Tutorial。 這個就是《Flask Web開發:基於Python的Web應用開發實戰》的原始博客。


500lines


推薦一個非常厲害的項目 GitHub - aosabook/500lines: 500 Lines or Less, 它裡面包含了22個由該領域的專家完成,用不到500行的代碼實現一個特定功能的子項目。連Guido van Rossum都親自來寫基於asyncio爬蟲了,Nick Coghlan、ajdavis也出場了。更具體的介紹可以看Python 的練手項目有哪些值得推薦? - 小小搬運工的回答。


最後再推薦一些更複雜的項目,可能不算練手的範疇,但是對於練手的技藝提高有很大幫助(您總不希望一直寫練手項目吧),可以學到更多的項目設計、編程技巧等方面的內容:


GitHub - pallets/jinja: The Jinja2 template engine

GitHub - mongodb/mongo-python-driver: PyMongo

GitHub - andymccurdy/redis-py: Redis Python Client

GitHub - getredash/redash: Make Your Company Data Driven. Connect to any data source, easily visualize and share your data.

GitHub - jmcarp/robobrowser

GitHub - idank/explainshell: match command-line arguments to their help text

GitHub - madisonmay/Tomorrow: Magic decorator syntax for asynchronous code in Python

GitHub - amoffat/sh: Python process launching

GitHub - jeffknupp/sandman: Sandman amp;amp;quot;makes things RESTamp;amp;quot;.

GitHub - benoitc/gunicorn: gunicorn amp;amp;#x27;Green Unicornamp;amp;#x27; is a WSGI HTTP Server for UNIX, fast clients and sleepy applications.

GitHub - jaraco/path.py: amp;amp;quot;Pathamp;amp;quot; object conveniently wrapping assorted file/path-related functionality

GitHub - grantjenks/sorted_containers: Python Sorted Container Types: SortedList, SortedDict, and SortedSet


如果強調 Pythonic,那麼 Pocoo 的作品非常值得讀,比如 Flask、Werkzeug。
https://speakerdeck.com/u/mitsuhiko


想寫好代碼,無它,唯有多寫,多看,多思考,多總結,要是還能分享一下就更好了。

隨便拿一個主流 python web框架來讀,裡面的代碼都很pythonic,初學python,還是一步一步來好,先自己寫, 在寫的過程中,如果是調用python庫,那麼你就可以點進去睹一睹。 然後看別人寫,讀讀別人總結的python技巧,比如: http://foofish.net/blog/25/,至於系統讀某個框架源碼除非你是想寫個類似的框架或者寫個更優秀的框架才去花大把時間在上面。


如果只是想更pythonic的代碼風格,不需要看任何實際項目的代碼。通讀PEP8即可。

另外學一門functional programming language對pythonic代碼風格的養成非常有益


GitHub上有人整理了一份,我給大家搬過來看看。

原頁面:programthink/opensource

1 演算法

1.1 字元串

1.1.1 正則表達式

re

【標準庫】

提供基於正則的匹配和替換。

1.1.2 字符集

chardet

Home:https://github.com/erikrose/chardet

chardet 可以猜測任意一段文本的字符集編碼。對於編碼類型未知的文本,它會很有用。

chardet 既可以作為模塊來使用,也可以作為命令行工具來使用。

代碼示例

import chardet
print(chardet.detect(bytes))

1.1.3 (其它)

StringIO cStringIO

【標準庫】

以讀寫文件的方式來操作字元串(有點類似於內存文件)。

cStringIO 是 C 語言實現的,性能更高;而 StringIO 是 Python 實現的,提供 Unicode 兼容性。

difflib

【標準庫】

可以對兩個字元串進行「按行」比較,其功能類似於命令行的 diff。

另外還支持「最佳匹配」功能——對給定的字元串 s 和字元串列表 l,在 l 裡面找到最接近 s 的字元串。

1.2 編碼 解碼

1.2.1 base64

Base64 是一組編碼演算法的總稱。用於把二進位數據編碼為文本。

base64

【標準庫】

提供 Base16、Base32、Base64 格式的編碼和解碼。

1.2.2 UUencode

UUencode 出現於早期的 Unix 系統。用於把二進位編碼為文本,以便通過郵件系統發送。

uu

【標準庫】

提供 UUencode 格式的編碼和解碼。

1.2.3 BinHex

BinHex 起先用於 Mac OS 系統,類似於 UUencode。

binhex

【標準庫】

提供 BinHex 格式的編碼和解碼。

1.3 數學類

math

【標準庫】

顧名思義,這個標準庫封裝了常用的數學函數(開方、指數、對數、三角函數......)。

random

【標準庫】

顧名思義,這個標準庫是用來進行隨機數生成滴。

代碼示例——生成 0-100 的隨機數

import random
random.seed()
random.randint(0, 100)

fractions

【標準庫】

封裝了跟有理數(分數)相關的運算

1.4 容器

pygtrie

Home:https://github.com/google/pytrie

這是 Google 實現的 trie(前綴樹/字典樹)封裝庫。

2 跨語言編程

Python 可以很容易地跟其它編程語言整合。整合之後,就可以在 Python 代碼中使用其它編程語言的函數、模塊、庫,非常爽!

2.1 整合 C C++

ctypes

ctypes 在 Python 2.5 版本加入到標準庫中。

通過它,你可以很方便地調用 C/C++ 動態庫導出的函數,可以在 Python 中使用各種 C/C++ 的數據類型(包括「指針」和「引用」)。

代碼示例——調用 Linux/Unix 系統的標準 C 函數,獲取當前時間

from ctypes import *

libc = CDLL("libc.so.6")
time = libc.time(None)

代碼示例——調用 Windows 系統的 API,彈出消息提示框

from ctypes import c_int, WINFUNCTYPE, windll
from ctypes.wintypes import HWND, LPCSTR, UINT

prototype = WINFUNCTYPE(c_int, HWND, LPCSTR, LPCSTR, UINT)
paramflags = (1, "hwnd", 0), (1, "text", "Hi"), (1, "caption", None), (1, "flags", 0)
MessageBox = prototype(("MessageBoxA", windll.user32), paramflags)
MessageBox(text="Hello, world", flags=2)

SWIG(Simplified Wrapper and Interface Generator)

Home:http://swig.org/

Links:Wikipedia

這是一個很老牌的、有名氣的工具,它可以把多種語言(Java、Python、C#、Ruby、PHP、Perl、Lua、Go ...)整合到 C/C++ 中。

Cython

Home:http://cython.org/

這個工具可以讓你用 Python 的語法寫擴展模塊的代碼,然後它幫你把 Python 代碼編譯為本地動態庫(機器碼)。

用它編譯出來的擴展模塊,其性能跟 C/C++ 編寫的擴展模塊相當。

2.2 整合 JVM 平台

Jython

Home:http://www.jython.org/

Links:Wikipedia 維基百科

通過 Jython 可以讓 Python 代碼運行在 JVM 上,並且可以調用其它的 JVM 語言的代碼(比如 Java、Scala)

2.3 整合 dotNet 平台

IronPython

Home:http://ironpython.net/

Links:Wikipedia 維基百科

通過 IronPython 可以讓 Python 代碼運行在 dotNET 平台上,並且可以調用其它的 dotNET 語言的代碼(C#、F#、http://VB.Net ...)

2.4 整合 Go

gopy

Home:https://github.com/go-python/gopy

gopy 可以把 Go 源代碼編譯為 Python 的一個 module。

它提供了兩種方式(命令行、Python 庫)來實現:Go 源碼編譯為 Python 模塊。

2.5 整合 Objective-C

PyObjC

Home:http://pyobjc.sourceforge.net/

這是用 Python 封裝 Mac OS X 上的 Objective-C 庫。

3 操作系統

3.1 文件和目錄操作

os

【標準庫】

這是非常基本的標準庫,提供了常見的操作系統相關功能,很多功能是針對文件系統。

shutil

【標準庫】

相對於 os 而言,shutil 提供了一些比較高級的文件和目錄操作(目錄遞歸複製、目錄遞歸刪除、目錄壓縮打包...)

代碼示例——遞歸刪除某個目錄

import shutil
shutil.rmtree(xxxx)

glob

【標準庫】

用於查找文件,【支持通配符】(* 和 ?)

代碼示例——獲取當前目錄所有 txt 文件

import glob
for file in glob.glob("./*.txt") :
print(file)

fnmatch

【標準庫】

用於匹配文件名(支持通配符,類似上面的 glob)

代碼示例——列出當前目錄所有 txt 文件

import os, fnmatch

for file in os.listdir(".") :
if fnmatch.fnmatch(file, "*.txt") :
print(file)

tempfile

【標準庫】

使用它可以安全地生成臨時文件或臨時目錄。

3.2 線程

threading

【標準庫】

提供了比較高層的線程封裝 API。它本身包含了線程同步/互斥的機制。

代碼示例——基於「函數」的線程

import threading
import time

def my_thread() :
print("Thread started!")
time.sleep(3)
print("Thread finished!")

threading.Thread(target=my_thread).start()

代碼示例——基於「類」的線程

import threading
import time
from __future__ import print_function

class MyThread(threading.Thread) :
def run(self) :
print("{} started!".format(self.getName()))
time.sleep(3)
print("{} finished!".format(self.getName()))

if __name__ == "__main__" :
for n in range(10) :
mythread = MyThread(name = "Thread-{}".format(n + 1))
mythread.start()
time.sleep(1)

3.3 進程

subprocess

【標準庫】

用於進程管理,可以啟動子進程,通過標準輸入輸出跟子進程交互。

代碼示例——啟動命令行進程,並獲取該進程的標準輸出

import subprocess
output = subprocess.check_output(["dir"]) # 獲取當前目錄的內容
output = subprocess.check_output(["netstat", "-an"]) # 獲取當前網路鏈接

multiprocessing

【標準庫】

它是 2.6 版本加入到標準庫的,其 API 介面的風格類似於 threading 模塊。

它本身包含了進程同步/互斥的機制。

代碼示例——利用其 Lock 機制,確保多個子進程的標準輸出不會混雜(每次只有一個進程調用 print)。

from multiprocessing import Process, Lock

def f(lock, n) :
lock.acquire()
print("hello world %d" % n)
lock.release()

if __name__ == "__main__" :
lock = Lock()
for num in range(10):
Process(target=f, args=(lock, num)).start()

3.4 本地進程間通信(IPC)

mmap

【標準庫】

提供了內存映射文件的支持。

代碼示例——利用 mmap 在父子進程間交換數據

import os
import mmap

map = mmap.mmap(-1, 13)
map.write("Hello, world")

pid = os.fork()
if pid == 0 : # 子進程
map.seek(0)
print(map.readline())
map.close()

signal

【標準庫】

用於進程信號處理的標準庫(主要用於 Linux UNIX 系統)。

3.5 Linux Unix 系統相關

syslog

【標準庫】

通過它可以很方便地跟 POSIX 的 syslog 服務進行交互。

3.6 Windows 系統相關

PyWin32

Home:http://python.net/crew/mhammond/win32/

這個第三方庫封裝了 Windows API 及 COM API。通過它可以方便地用 Python 進行 Windows 編程(調用 COM 組件、編寫 Windows 服務、等)。

3.7 程序打包

PyInstaller

Home:http://www.pyinstaller.org/

PyInstaller 可以把你的 Python 代碼製作成獨立運行的程序(不依賴 Python 環境就可以運行)。

該工具支持多種操作系統,包括:Windows、Linux、Mac OS X、Solaris、AIX、等。

py2exe

Home:http://www.py2exe.org/

Links:Wikipedia

py2exe 的功能類似 PyInstaller,但只支持 Windows 平台。

py2app

Home:https://bitbucket.org/ronaldoussoren/py2app

它很類似於 py2exe,差別在於 py2exe 支持 Windows 平台,而 py2app 支持 Mac OS X 平台。

EasyInstall Setuptools

Home:https://pypi.python.org/pypi/setuptools

這套工具可以幫助你進行第三方庫的管理(下載、編譯、安裝、升級、卸載)

4 Web

4.1 HTTP Client

httplib httplib2 http.request urllib.parse

【標準庫】

這幾個庫可以進行各種 HTTP 客戶端請求(GET、POST、等)。

Python2 的模塊名是 httplib 和 httplib2;到 Python3,模塊名改為 http.request 和 urllib.parse

代碼示例——讀取指定 URL 的網頁內容

import urllib
handle = urllib.urlopen("http://www.google.com")
page = handle.read()
handle.close()

Requests

Home:http://www.python-requests.org/

這是一個用起來很優雅的庫,如其名,封裝了 HTTP 請求的功能。

代碼示例

&>&>&> r = requests.get("https://api.github.com/user", auth=("user", "pass"))
&>&>&> r.status_code
200
&>&>&> r.headers["content-type"]
"application/json; charset=utf8"
&>&>&> r.encoding
"utf-8"
&>&>&> r.text
u"{"type":"User"..."
&>&>&> r.json()
{u"private_gists": 419, u"total_private_repos": 77, ...}

4.2 HTTP Server

SimpleHTTPServer http.server

【標準庫】

提供輕量級 HTTP Server 的標準庫。

Python2 的模塊名叫 SimpleHTTPServer;到 Python3 模塊名改為 http.server

代碼示例——一個極簡單的 HTTP 服務

import SocketServer
import SimpleHTTPServer

PORT = 8080
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
print("serving at port %d" % PORT)
httpd.serve_forever()

4.3 Web 開發框架

(Python 的 Web 框架數不勝數,俺只挑選幾個代表性的)

Django

Home:https://www.djangoproject.com/

Links:Wikipedia 維基百科

在 Python 社區,Django 是目前最有影響力的 Web 開發框架。該框架很重型,內置了 Web 服務端開發常用的組件(比如:ORM、用戶管理)。

Django 應用範圍很廣,比如 Google 的 Web 開發平台 GAE 就支持它。

而且它完全支持前面提到的 Jython 運行環境,可以運行在任何 J2EE 伺服器上。

TurboGears

Home:http://www.turbogears.org/

Links:Wikipedia 維基百科

又一個重型的 Web 開發框架,名氣僅次於 Django。

它跟 Django 一樣,都是「Full-Stack Frameworks」。

CherryPy

Home:http://www.cherrypy.org/

Links:Wikipedia

輕量級的 Web 框架。某些 Web 框架(比如前面提到的 TurboGears)使用它作為底層。

代碼示例——Hello world

import cherrypy

class HelloWorld(object):
def index(self):
return "Hello World!"
index.exposed = True

cherrypy.quickstart(HelloWorld())

web.py

Home:http://webpy.org/

與前兩個(Django、TurboGears)不同,這是一個輕量級的框架。甚至被稱為「It"s the anti-framework framework.」

其作者是大名鼎鼎的黑客 Aaron Swartz。(俺在某篇博文中悼念過他)。

當年 Aaron Swartz 用 web.py 來搭建同樣大名鼎鼎的網站 reddit(該網站是 Web 2.0 的標杆)。

代碼示例——Hello world

import web

urls = (
"/", "index"
)

class index:
def GET(self):
return "Hello, world!"

if __name__ == "__main__" :
app = web.application(urls, globals())
app.run()

4.4 Web前端 JS整合

Pyjamas pyjs

Home:http://pyjs.org/

這是從 GWT(Google Web Toolkit)移植的第三方庫。提供了 Python 到 JS 的編譯,AJAX 框架等功能。

Pyjamas 甚至能用來開發桌面 GUI 應用。

pyjaco

Home:https://github.com/chrivers/pyjaco

這也是一個 Python 到 JavaScript 的編譯工具。

4.5 瀏覽器整合

webbrowser

【標準庫】

操縱當前系統的默認瀏覽器,訪問指定 URL 的頁面。

代碼示例——用默認瀏覽器打開 Google 主頁

import webbrowser
webbrowser.open("http://www.google.com")

pyv8

Home:https://pypi.python.org/pypi/PyV8

v8 是 Google 開發的 JavaScript 解釋引擎。這是對 v8 引擎的 Python 封裝。

代碼示例

import PyV8

ctxt1 = PyV8.JSContext()
ctxt1.enter()
ctxt1.eval("1+2") # 對 JS 表達式求值

class Global(PyV8.JSClass) : # 定義一個兼容 JS 的類
def hello(self) :
print("Hello, world")

ctxt2 = PyV8.JSContext(Global()) # 創建一個 JS 上下文,傳入 Global 類的對象
ctxt2.enter()
ctxt2.eval("hello()") # 調用 hello() 函數

PyWebKitGtk

Home:https://github.com/jmalonzo/pywebkitgtk

WebKitGtk 是一個基於 WebKit 的 Web 渲染引擎。

PyWebKitGtk 則提供了對 WebKitGtk 的 Python 封裝。

4.6 (其它)

pywebsocket

Home:https://github.com/google/pywebsocket

這是 Google 提供的 WebSocket 服務端。

該項目包含一個可獨立運行的 server 以及一個 Apache 擴展模塊(mod_pywebsocket)。

5 網路

5.1 鏈路層 網路層

Scapy

Home:http://www.secdev.org/projects/scapy/

Links:Wikipedia

這是一個底層的網路庫,可以在不同協議層次構造網路數據包(包括鏈路層、網路層、傳輸層),還支持 Sniffer 抓包。

搞網路安全的網友應該會喜歡這個庫。

代碼示例

# 傳統的 ping 掃描(網路層)
ans,unans = sr(IP(dst="192.168.1.1-254")/ICMP())

# 區域網內的 ARP 掃描(鏈路層)
ans,unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="192.168.1.0/24"), timeout=2)

5.2 傳輸層

socket

Python 標準庫很早就提供了對 socket 編程的支持。

這個標準庫是對伯克利套接字進行簡單的封裝,其 API 基本上跟 BSD SOCKET 一一對應。

asyncore

這個標準庫提供了非同步 SOCKET 的支持。

asynchat

這個標準庫基於上述的 asyncore,提供更高層的 API,簡化非同步通訊編程。

5.3 標準的應用層

5.3.1 綜合性的庫

PycURL

Home:http://pycurl.sourceforge.net/

cURL 是一個功能很強的網路庫/網路工具,支持 N 多應用層協議。俺在前幾年寫過一篇博文推薦它(在「這裡」)。

看名稱就能猜到——PycURL 是 cURL 的 Python 封裝。

代碼示例——發起 HTTP GET 請求

import pycurl
try :
from io import BytesIO
except ImportError :
from StringIO import StringIO as BytesIO

buffer = BytesIO()
curl = pycurl.Curl()
curl.setopt(curl.URL, "http://pycurl.sourceforge.net/")
curl.setopt(curl.WRITEDATA, buffer)
curl.perform()
curl.close()
body = buffer.getvalue()

5.3.2 HTTP

(關於「HTTP 協議」,請參見另一個大類:「Web」)

5.3.3 文件傳輸

ftplib

【標準庫】

封裝 FTP(File Transfer Protocol)協議

代碼示例——列出 FTP 伺服器上某目錄的內容

from ftplib import FTP

ftp = FTP("ftp.debian.org") # 連接伺服器(如果不指定埠號,則用默認埠號 21)
ftp.login() # 登錄(如果不指定用戶名和密碼,則用匿名登錄)
ftp.cwd("debian") # 切換到 "debian" 目錄
ftp.retrlines("LIST") # 列出當前目錄的內容
ftp.quit()

pysftp

Home:https://bitbucket.org/dundeemt/pysftp

封裝 SFTP 協議,依賴於 ssh.py

代碼示例——簡單的上傳/下載

import pysftp

with pysftp.Connection("hostxxx", username="userxxx", password="xxxxxx") as sftp :
with sftp.cd("public") # 服務端當前目錄切換到 public
sftp.put("/my/local/filename") # 上傳某個本地文件到服務端的 public 目錄
sftp.get_r("myfiles", "/local") # 遞歸複製某個服務端的目錄到本地

5.3.4 電子郵件

smtplib

【標準庫】

封裝 SMTP(Simple Mail Transfer Protocol)協議

imaplib

【標準庫】

封裝 IMAP(Internet Message Access Protocol)協議

poplib

【標準庫】

封裝 POP3(Post Office Protocol v3)協議

5.3.5 即時通訊

jabber.py

Home:http://jabberpy.sourceforge.net/

Jabber(又稱 XMPP)是IM(即時通信)協議的標準。這是用 Python 封裝的第三方庫。

irclib

Home:https://bitbucket.org/jaraco/irc

IRC 是 Internet Relay Chat 的縮寫。這是用 Python 封裝的第三方庫。

5.3.6 遠程控制

telnetlib

【標準庫】

封裝 telnet 協議

代碼示例——使用 telnet 登錄到某個主機並執行簡單命令

import telnetlib
import getpass

host = raw_input("Enter remote host: ")
user = raw_input("Enter your remote account: ")
password = getpass.getpass()

tn = telnetlib.Telnet(host)

tn.read_until("login: ")
tn.write(user + "
")

if password :
tn.read_until("Password: ")
tn.write(password + "
")

tn.write("ls
")
tn.write("exit
")

print tn.read_all()

rdpy

Home:https://github.com/citronneur/rdpy

純 Python 實現的 RDP(微軟遠程桌面協議)和 VNC(Virtual Network Computing)客戶端,依賴於 Twisted 庫

5.3.7 (其它)

urlparse

【標準庫】

用於解析 URL,提取各個部分的內容。從 Python 2.5 版本開始加入到標準庫中,從 Python 2.7 開始支持包含 IPv6 的 URL

5.4 自定義的應用層

Protocol Buffers

Home:https://developers.google.com/protocol-buffers/

Links:Wikipedia

這是 Google 開發的一個跨語言的庫,用於網路傳輸業務數據時的「編碼/解碼」。

其優點是:跨多種語言、高性能、向前兼容、向後兼容。俺前幾年寫過一篇博文推薦 protobuf(在「這裡」)。

作為 Protocol Buffers 的發明者,Google 默認實現了三種編程語言(C++、Java、Python)對它的支持。

Apache Thrift

Home:https://thrift.apache.org/

Links:Wikipedia

來自於 Apache 社區,提供了一種跨語言的通訊機制。

程序員通過 Thrift 的「介面定義語言」定義通訊協議格式,然後 Thrift 根據協議格式自動幫你生成服務端和客戶端代碼。

(在這個方面,它有點類似於 Google 的 Protocol Buffers)

5.5 網路庫、框架、中間件

Twisted

Home:http://twistedmatrix.com/

Links:Wikipedia

這是一個基於 Python 網路通訊開發框架,誕生於2002年,名氣很大。

它的某些設計類似於 C++ 的 ACE 框架。除了能用來進行傳輸層(TCP UDP)的開發,還提供了若干應用層協議(HTTP、XMPP、SSH、IRC ...)的支持。

代碼示例——實現一個簡單的 Echo 服務,監聽在 12345 埠

from twisted.internet import protocol, reactor

class Echo(protocol.Protocol) :
def dataReceived(self, data) :
self.transport.write(data)

class EchoFactory(protocol.Factory) :
def buildProtocol(self, addr) :
return Echo()

reactor.listenTCP(12345, EchoFactory())
reactor.run()

gevent

Home:http://www.gevent.org/

這是一個基於協程的網路庫,原先其底層依賴於 libevent,後來改為 libev。

很多開源項目用到了 gevent,具體參見 gevent 官方的 wiki。

代碼示例——並發執行網路請求

from gevent import socket
import gevent

hosts = ["google.com", "github.com", "program-think.blogspot.com"]
jobs = [gevent.spawn(socket.gethostbyname, host) for host in hosts]
gevent.joinall(jobs, timeout=2)
print([job.value for job in jobs])

PyZMQ

Home:https://github.com/zeromq/pyzmq

這是 ZMQ(ZeroMQ)的 Python 封裝庫。同時支持 Python2 和 Python3。

PyZMQ 2.2 之後的版本同時支持 ZMQ 的 3.x 和 4.x 版本。

nanomsg-python

Home:https://github.com/tonysimpson/nanomsg-python

這是 nanomsg 的 Python 封裝庫。同時支持 Python2 和 Python3。

代碼示例——Hello world

from __future__ import print_function
from nanomsg import Socket, PAIR, PUB

s1 = Socket(PAIR)
s2 = Socket(PAIR)
s1.bind("inproc://test")
s2.connect("inproc://test")
s1.send(b"hello world")
print(s2.recv())
s1.close()
s2.close()

5.6 雲計算

Apache Libcloud

Home:https://libcloud.apache.org/

如今雲提供商越來越多。這個庫提供了統一的 API 讓你訪問各大知名雲提供商提供的各種服務。

代碼示例——創建 DNS 記錄

from libcloud.dns.types import Provider, RecordType
from libcloud.dns.providers import get_driver

cls = get_driver(Provider.ZERIGO)
driver = cls("email", "api key")

zones = driver.list_zones()
zone = [zone for zone in zones if zone.domain == "mydomain.com"][0]

record = zone.create_record(name="www", type=RecordType.A, data="127.0.0.1")
print(record)

6 資料庫

為了便於資料庫開發,Python 社區制定了資料庫的 API 規範(PEP 249)。

只要是涉及到資料庫操作,標準庫和大部分第三方庫都會遵循該規範(請看如下幾個模塊的示例代碼)。

6.1 資料庫中間件

6.1.1 ODBC

pyODBC

Home:https://github.com/mkleehammer/pyodbc

pyODBC 封裝了 ODBC API,通過它可以訪問各種資料庫(只要有 ODBC 驅動即可)。

代碼示例——查詢某個 ODBC 數據源的某個表

import pyodbc

conn = pyodbc.connect("DSN=xxx;PWD=password")
cursor = conn.cursor()
cursor.execute("SELECT field1 FROM table1")

while True :
row = cursor.fetchone()
if not row :
break
print(row)

cursor.close()
conn.close()

ceODBC

Home:http://ceodbc.sourceforge.net/

又一個封裝 ODBC API 的第三方庫

6.1.2 JDBC

Jython

Jython 前面已經介紹過。有了它,你可以基於 JDBC 操作資料庫。

6.1.3 ADO http://ADO.NET

PyWin32

PyWin32 前面已經介紹過。有了它,你可以基於 ADO 操作資料庫。

IronPython

IronPython 前面已經介紹過。有了它,你可以基於 ADO.NET 操作資料庫。

6.2 特定資料庫

6.2.1 MySQL

MySQL for Python

Home:http://mysql-python.sourceforge.net/

操作 MySQL 的第三方庫。

代碼示例——查詢某個 MySQL 資料庫的某個表

import MySQLdb

conn = MySQLdb.connect(db="test", passwd="password")
cursor = conn.cursor()
cursor.execute("SELECT field1 FROM table1")

while True :
row = cursor.fetchone()
if not row :
break
print(row)

cursor.close()
conn.close()

6.2.2 PostgreSQL

psycopg

Home:http://initd.org/psycopg/

操作 PostgreSQL 的第三方庫。

PyGreSQL

Home:http://www.pygresql.org/

操作 PostgreSQL 的第三方庫。

6.2.3 Oracle

cx_Oracle

Home:http://cx-oracle.sourceforge.net/

操作 Oracle 的第三方庫。

6.2.4 MS SQL Server

pymssql

Home:http://pymssql.org/

操作微軟 SQL Server 的第三方庫。

6.2.5 IBM DB2

ibm-db

Home:https://pypi.python.org/pypi/ibm_db

操作 DB2 的第三方庫。

6.2.6 SQLite

sqlite3

【標準庫】

sqlite3 從 Python 2.5 版本開始加入到標準庫中。通過它,你可以很方便地操作 SQLite 資料庫。

SQLite 是一個很優秀的輕量級資料庫,俺前幾年寫過一篇博文推薦它(在「這裡」)。

代碼示例——創建一個內存資料庫,建表並插入記錄

import sqlite3
conn = sqlite3.connect(":memory:") # ":memory:" 表示這是一個內存資料庫
cursor = conn.cursor()
cursor.execute("CREATE TABLE person (name text, age int)")
cursor.execute("INSERT INTO stocks VALUES ("TOM",20)")
conn.commit()
conn.close()

6.2.7 MongoDB

PyMongo

Docs:https://docs.mongodb.com/ecosystem/drivers/python/

這是 MongoDB 官方提供的 Python 驅動。

6.2.8 Apache HBase

HappyBase

Home:https://github.com/wbolster/happybase

操作 HBase 的 Python 庫,基於 Thrift 連接到 HBase。

代碼示例——簡單的存取操作

import happybase
connection = happybase.Connection("hostname")
table = connection.table("table-name")
table.put(b"row-key", {b"test1": b"data1", b"test2": b"data2"})
row = table.row(b"row-key")
print(row[b"test1"])

6.2.9 Redis

redis-py

Home:https://github.com/andymccurdy/redis-py

操作 Redis 的第三方 Python 客戶端。

代碼示例——簡單的存取操作

import redis
r = redis.StrictRedis(host="localhost", port=6379, db=0)
r.set("foo", "bar")
print(r.get("foo"))

6.2.10 LevelDB

Plyvel

Home:https://github.com/wbolster/plyvel

操作 LevelDB 的 Python 庫,速度快,同時兼容 Python2 和 Python3。

代碼示例——簡單的存取操作

import plyvel
db = plyvel.DB("/tmp/testdb/", create_if_missing=True)
db.put(b"key", b"value")
print(db.get(b"key"))
db.close()

6.2.11 Berkeley DB

PyBSDDB

Home:http://www.jcea.es/programacion/pybsddb.htm

操作 Berkeley DB 的第三方庫。

6.3 ORM(Object-Relational Mapping)

SQLAlchemy

Home:http://www.sqlalchemy.org/

Links:Wikipedia 維基百科

SQLAlchemy 支持的資料庫有:MySQL、PostgreSQL、Sqlite、Oracle、MS SQL Server、Firebird、Sybase SQL Server、Informix、等。

代碼示例——通過對象的方式創建兩張依賴關係的表

from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relation, sessionmaker

Base = declarative_base()

class Movie(Base) :
__tablename__ = "movies"

id = Column(Integer, primary_key=True)
title = Column(String(255), nullable=False)
year = Column(Integer)
directed_by = Column(Integer, ForeignKey("directors.id"))
director = relation("Director", backref="movies", lazy=False)

def __init__(self, title=None, year=None) :
self.title = title
self.year = year

def __repr__(self) :
return "Movie(%r, %r, %r)" % (self.title, self.year, self.director)

class Director(Base) :
__tablename__ = "directors"

id = Column(Integer, primary_key=True)
name = Column(String(50), nullable=False, unique=True)

def __init__(self, name=None) :
self.name = name

def __repr__(self) :
return "Director(%r)" % (self.name)

Base.metadata.create_all(create_engine("dbms://user:pwd@host/dbname"))

SQLObject

Home:http://sqlobject.org/

Links:Wikipedia

SQLObject 支持的資料庫有:MySQL、PostgreSQL、Sqlite、MS SQL Server、Firebird、Sybase SQL Server、SAP DB、等。

代碼示例——通過對象的方式創建表

from sqlobject import *
sqlhub.processConnection = connectionForURI("sqlite:/:memory:")

class Person(SQLObject) :
first_name = StringCol()
last_name = StringCol()

Person.createTable()

Peewee

Home:http://www.peewee-orm.com/

一個輕量級的 ORM,支持 SQLite、MySQL 和 PostgreSQL,通過插件機制支持更多資料庫。

同時支持 Python2 和 Python3。

代碼示例——通過對象的方式創建表

from peewee import *

db = SqliteDatabase("test.db")

class Person(Model) :
name = CharField()
birthday = DateField()
is_relative = BooleanField()
class Meta :
database = db # This model uses the "test.db".

class Pet(Model) :
owner = ForeignKeyField(Person, related_name="pets")
name = CharField()
animal_type = CharField()
class Meta :
database = db # This model uses the "test.db".

db.connect()
db.create_tables([Person, Pet])

7 GUI

7.1 GUI 框架

7.1.1 基於 Tk

Tk 是一個跨平台的界面組件庫。

Tkinter tkinter

【標準庫】

這是 Python 內置的標準庫,封裝了 Tcl/Tk 界面庫。

Python2 的模塊名叫 Tkinter,到 Python3 模塊名改為 tkinter

代碼示例——用 Tkinter 寫 Hello world

from Tkinter import *

if __name__ == "__main__" :
root = Tk()
label = Label(root, text="Hello, world")
label.pack()
root.mainloop()

7.1.2 基於 wxWidgets

wxWidgets 是 C++ 開發的跨平台框架(不僅包括 GUI,還有其它功能)。

wxPython

Home:http://www.wxpython.org/

Links:Wikipedia 維基百科

在所有的 wxWidgets 的 Python 封裝庫中,這個是名氣最大的。

Ulipad(知名的國產的 Python IDE)就是基於 wxPython 開發的。

代碼示例——用 wxPython 寫 Hello world

import wx

class Frame(wx.Frame) :
pass

class App(wx.App) :
def OnInit(self) :
self.frame = Frame(parent=None, title="Hello, world")
self.frame.Show()
self.SetTopWindow(self.frame)
return True

if __name__ == "__main__" :
app = App()
app.MainLoop()

PythonCard

Home:http://pythoncard.sourceforge.net/

又一個基於 wxWidgets 的 GUI 庫。

7.1.3 基於 GTK+

GTK+ 全稱是(GIMP Toolkit),由 C 開發的跨平台界面組件庫。

PyGTK

Home:http://www.pygtk.org/

Links:Wikipedia

它是 Python 對 GTK+2 的封裝。

代碼示例——用 PyGTK 寫 Hello world

import pygtk
pygtk.require("2.0")
import gtk

class HelloWorld :
def __init__(self) :
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.connect("delete_event", self.delete_event)
self.window.connect("destroy", self.destroy)
self.window.set_border_width(10)

self.button = gtk.Button("Hello, world")
self.button.connect("clicked", self.hello, None)
self.button.connect_object("clicked", gtk.Widget.destroy, self.window)
self.window.add(self.button)

self.button.show()
self.window.show()

def main(self) :
gtk.main()

def hello(self, widget, data=None) :
print("Hello, world")

def delete_event(self, widget, event, data=None) :
print("delete event occurred")
return False

def destroy(self, widget, data=None) :
gtk.main_quit()

if __name__ == "__main__" :
hello = HelloWorld()
hello.main()

PyGObject(PyGI)

Home:https://live.gnome.org/PyGObject

它是 Python 對 GTK+3 的封裝。PyGTK 的官網也推薦它。

代碼示例——用 PyGObject 寫 Hello world

from gi.repository import Gtk

class MyWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Hello World")

self.button = Gtk.Button(label="Click Here")
self.button.connect("clicked", self.on_button_clicked)
self.add(self.button)

def on_button_clicked(self, widget):
print("Hello, world!")

win = MyWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()

7.1.4 基於 Qt

Qt 是 C++ 開發的跨平台框架(不僅包括 GUI,還有其它功能)。

PyQt

Home:http://www.riverbankcomputing.com/software/pyqt/

Links:Wikipedia 維基百科

這是 Python 對 Qt 的封裝。

代碼示例——用 pyQt 寫 Hello world

import sys
from PyQt4.QtGui import *

if __name__ == "__main__" :
app = QApplication(sys.argv)
window = QWidget()

window.resize(320, 240)
window.setWindowTitle("Hello, world")
window.show()
sys.exit(app.exec_())

PySide

Home:http://www.pyside.org/

這也是 Python 對 Qt 的封裝。

7.1.5 基於 FLTK

FLTK 全稱是(Fast Light Tool Kit),由 C++ 開發的跨平台、輕量級界面組件庫。

PyFLTK

Home:http://pyfltk.sourceforge.net/

這是 Python 對 FLTK 的封裝。

7.1.6 基於 Windows 平台

PyWin32

PyWin32 前面已經介紹過。它可以提供原生的 Windows GUI 界面。

IronPython

IronPython 前面已經介紹過。它可以提供 dotNET 的 GUI 界面。

7.1.7 基於 JVM 平台

Jython

Jython 前面已經介紹過。它可以提供基於 Java 的 Swing 界面。

7.1.8 (其它)

EasyGUI

Home:http://easygui.sourceforge.net/

EasyGUI 這是一個很輕量級的庫。跟其它 GUI 不同之處在於——它沒有「事件驅動」。

PyGUI

Home:http://www.cosc.canterbury.ac.nz/greg.ewing/python_gui/

PyGUI 是一個更高層的 GUI 庫,底層分別封裝了 PyWin32(Windows 平台)、PyGTK(Linux 平台)、PyObjC(Mac OS X 平台)。

Kivy

Home:http://kivy.org/

跨平台的多媒體框架和界面庫,用來開發比較炫的界面。

除了支持桌面操作系統,還支持 Android / iOS,支持多點觸摸。

OcempGUI

Home:http://ocemp.sourceforge.net/gui.html

基於 PyGame 的一個跨平台 GUI 庫(PyGame 下面會提到)。

7.2 圖表 報表

matplotlib

Home:http://matplotlib.org/

Links:Wikipedia

這是一個有名的圖形庫,主要用來繪製數學相關的圖形。

它跟後面提到的 SciPy 整合可以起到類似 MATLAB 的效果。效果圖在「這裡」。

Gnuplot.py

Home:http://gnuplot-py.sourceforge.net/

這是 Python 對 gnuplot 的封裝。gnuplot 的效果圖在「這裡」。

PyQtGraph

Home:http://www.pyqtgraph.org/

這是一個純 Python 的庫,依賴於 PyQt4 / PySide。效果圖在「這裡」。

PyX

Home:http://pyx.sourceforge.net/

這個庫可以跟 TeX / LaTeX 無縫整合,支持導出為 PostScript / PDF 格式。適合用來製作報表。效果圖在「這裡」。

Chaco

Home:http://code.enthought.com/chaco/

這是一個商業公司維護的庫,主要提供2維圖表。效果圖在「這裡」。

8 信息安全

8.1 密碼學

hashlib

【標準庫】

在 Python 2.5 版本加入到標準庫中。通過它,你可以很方便地計算各種散列值。

它支持的哈希演算法有:MD5 SHA1 SHA224 SHA256 SHA384 SHA512

關於散列演算法,俺寫過一篇掃盲(在「這裡」)。

代碼示例——計算字元串的 SHA1 散列值

import hashlib
sha1 = hashlib.sha1("Hello, world").hexdigest()

PyCrypto

Home:http://www.dlitz.net/software/pycrypto/

這個庫包含了常見的對稱加密演算法(DES、AES、IDEA 等)、公鑰加密演算法(RSA、DSA 等)、散列演算法(MD5、SHA1、RIPEMD 等)。

pyOpenSSL

Home:http://pyopenssl.sourceforge.net/

OpenSSL 在加密領域可是大名鼎鼎。這個庫使用 Python 對 OpenSSL 進行很薄的封裝。

Keyczar

Home:https://github.com/google/keyczar

這是 Google 提供的加密庫,同時提供 C++、Java、Python 三種語言的實現。

它提供了比較高層的 API, 使用者無需關心太多的細節。

8.2 訪問控制

oauth2client

Home:https://github.com/google/oauth2client

這是 Google 提供的 OAuth 客戶端,支持 OAuth 2.0 規範。

9 處理文件格式

9.1 結構化數據格式

9.1.1 CSV

CSV 是一種歷史悠久的結構化數據存儲格式。其效果類似於一張資料庫二維表。

csv

【標準庫】

提供 CSV 格式文件的讀寫,可以手動指定行列分隔符。

9.1.2 JSON

JSON 格式源自 JavaScript,如今在 Web 開發中廣為應用。

json

【標準庫】

提供 JSON 格式的編碼和解碼。

代碼示例——編碼/解碼 JSON 字元串

import json

json.dumps(["foo", {"bar": ("baz", None, 1.0, 2)}])
# JSON 編碼
# 得到如下【字元串】
# """["foo", {"bar": ["baz", null, 1.0, 2]}]"""

json.loads("""["foo", {"bar":["baz", null, 1.0, 2]}]""")
# JSON 解碼
# 得到如下【對象】
# [u"foo", {u"bar": [u"baz", None, 1.0, 2]}]

9.1.3 YAML

YAML 是一種類似於 json 的結構化數據格式。它在確保可讀性的基礎上,提供了超越 json 的靈活性和擴展性。

PyYAML

Home:http://pyyaml.org/

pyyaml 提供了 Python 對 YAML 的封裝。

9.2 壓縮文件 打包文件

9.2.1 zip

zipfile

【標準庫】

提供對 zip 格式的讀寫。

9.2.2 bzip2(bz2)

bz2

【標準庫】

提供對 bzip2 格式的讀寫。

9.2.3 gzip(gz)

gzip

【標準庫】

提供對 gzip 格式的讀寫。

zlib

【標準庫】

提供對 zlib 格式的讀寫。

9.2.4 tar

tarfile

【標準庫】

提供對 tar 格式的讀寫。

9.2.5 7zip(7z)

PyLZMA

Home:http://www.joachim-bauch.de/projects/pylzma/

處理 7zip 格式的第三方庫。

9.2.6 rar

rarfile

Home:http://rarfile.berlios.de/

處理 rar 格式的第三方庫。

9.2.7 msi

msilib

【標準庫】

提供對 msi 格式的讀寫,從 Python 2.5 版本開始加入標準庫。

9.3 標記語言

9.3.1 XML

xml.dom xml.miniDom xml.etree.ElementTree

【標準庫】

用 DOM(Document Object Model)方式處理 XML 文件。

xml.sax xml.parsers.expat

【標準庫】

用 SAX(Simple API for XML)方式處理 XML 文件。

lxml

Home:http://lxml.de/

著名的 C 語言庫 libxml 和 libxslt 的 Python 封裝。

功能很強,支持 XPath 1.0、XSLT 1.0、擴展 EXSLT、等。還可以用來解析 HTML 格式。

9.3.2 HTML

HTMLParser

【標準庫】

以回調方式解析 HTML/XHTML 文件內容。

9.4 PDF

pyfpdf

Home:https://github.com/reingart/pyfpdf

這是 FPDF 的 Python 移植庫,用來生成 PDF 文檔。

支持的功能比較全(嵌入字體、嵌入圖片),文檔也比較詳細。

代碼示例——簡單的 Hello World 示例

from fpdf import FPDF

pdf = FPDF()
pdf.add_page()
pdf.set_font("Arial", "B", 16)
pdf.cell(40, 10, "Hello, World")
pdf.output("test.pdf", "F")

代碼示例——支持寫入 HTML 語法(目前支持幾種常見的 HTML tag)

from pyfpdf import FPDF, HTMLMixin

class MyFPDF(FPDF, HTMLMixin) :
pass

pdf = MyFPDF()
pdf.add_page()
pdf.write_html(html)
pdf.output("test.pdf", "F")

pyPdf PyPDF2

Home:http://knowah.github.com/PyPDF2/

pyPdf 目前已經不繼續升級維護了。PyPDF2 是從 pyPdf 派生出來的,並繼續增加新功能。

它除了可以提取文件屬性,還可以切分/合併文檔,加密/解密文檔。

PDFMiner

Home:http://www.unixuser.org/~euske/python/pdfminer/

它可以提取 PDF 文件屬性以及每頁的文本,支持把內容輸出為 HTML 格式。

9.5 MS Office 文檔

9.5.1 Word(doc、docx)

python-docx

Home:https://github.com/python-openxml/python-docx

純 python 實現的 docx 操作庫,能夠處理 docx 中的「文本、圖片、樣式」。

同時支持 Python2 和 Python3。

PyWin32

PyWin32 前面已經介紹過。它可以基於 COM 操作 Office 文檔,包括 Word。

(本地需要安裝 Office)

9.5.2 Excel(xls、xlsx)

pyExcelerator

Home:http://sourceforge.net/projects/pyexcelerator/

它可以支持 Office Excel(97/2000/XP/2003)以及 OpenOffice Calc 的文檔。無需依賴外部軟體。

PyWin32

PyWin32 前面已經介紹過。它可以基於 COM 操作 Office 文檔,包括 Excel。

(本地需要安裝 Office)

9.5.3 Power Point(ppt、pptx)

python-pptx

Home:https://github.com/scanny/python-pptx

它可以用來生成 pptx(Open XML PowerPoint)格式的文檔。

PyWin32

PyWin32 前面已經介紹過。它可以基於 COM 操作 Office 文檔,包括 Power Point。

(本地需要安裝 Office)

9.6 RTF

PyRTF

Home:http://pyrtf.sourceforge.net/

它可以用來處理 RTF(富文本格式)文檔。

9.7 CHM

PyCHM

Home:http://gnochm.sourceforge.net/pychm.html

這是基於 chmlib 的 Python 封裝庫。可以提取 CHM 文件的屬性以及每個頁面的內容。

10 圖像

10.1 圖像處理

Python Imaging Library(PIL)

Home:http://www.pythonware.com/products/pil/

Links:Wikipedia

這是一個很有名氣的 Python 圖像處理庫,支持常見圖像文件格式(BMP、JPG、GIF、PNG ...)。

它可以對圖像進行各種常見的處理(旋轉、縮放、剪切 ...)。

代碼示例——為某個目錄下所有 JPEG 創建縮略圖

import os, glob
from PIL import Image

size = 128, 128
for file in glob.glob("*.jpg"):
name, ext = os.path.splitext(file)
img = Image.open(file)
img.thumbnail(size)
img.save(name+".thumbnail", "JPEG")

代碼示例——旋轉某圖片並顯示

from PIL import Image

img = Image.open("xxx.jpg")
img = img.rotate(90)
img.show()

Wand

Home:http://docs.wand-py.org/

它通過前面提到 ctypes 實現了對 ImageMagick 的封裝(ImageMagick 是最強大的開源圖片處理工具集)。

代碼示例——旋轉並縮放某圖片

from wand.image import Image
from wand.display import display

with Image(filename="mona-lisa.png") as img :
print(img.size)
for r in 1, 2, 3 :
with img.clone() as new_img :
new_img.resize(int(new_img.width/2), int(new_img.height/2))
new_img.rotate(90 * r)
new_img.save(filename="mona-lisa-{0}.png".format(r))
display(new_img)

Pillow

Home:http://python-pillow.org/

你可以把它視作「輕量級的 PIL」。

它的目標是比 PIL 更容易使用,並儘可能與 PIL 的 API 兼容。

PyGraphviz

Home:https://github.com/pygraphviz/pygraphviz

Graphviz 是一個功能很強大的關係圖【自動】生成工具,具體介紹可以參見俺的博文(在「這裡」)

這個庫如其名所示,提供了 Python 對 Graphviz 的封裝(基於 SWIG)。

Graphviz

Home:https://github.com/xflr6/graphviz

這個庫與上一個類似,也提供了 Graphviz 的 Python 的封裝。

這兩個庫都在 GitHub 上。(可能是因為出現較晚)這個庫的 Star 和 Fork 數都不如上一個,不過俺感覺文檔比較全。

代碼示例——創建一個 DOT 圖並加入若干節點和連線

from graphviz import Digraph

dot = Digraph(comment="The Round Table")
# 添加節點
dot.node("A", "King Arthur")
dot.node("B", "Sir Bedevere the Wise")
dot.node("L", "Sir Lancelot the Brave")
# 添加連線
dot.edges(["AB", "AL"])
dot.edge("B", "L", constraint="false")

10.2 圖像格式轉換

Python Imaging Library(PIL)

PIL 前面已經介紹過。它支持常見圖像文件格式(BMP、JPG、GIF、PNG ...)之間的相互轉換。

Wand

Wand 前面已經介紹過。由於它是針對 ImageMagick 的封裝。只要 ImageMagick 能轉換的格式,它也可以轉換。

10.3 圖像渲染

Pycairo

Home:http://cairographics.org/pycairo/

Cairo 是一個圖像渲染引擎,提供了矢量圖像的渲染功能。支持多種後端輸出(包括:Win32 GDI、OpenGL、Xlib、XCB、PDF、PNG、SVG......)。

Pycairo 是 Cairo 官方提供 Python 封裝。

11 遊戲

11.1 綜合性的遊戲引擎

PyGame

Home:http://www.pygame.org/

Links:Wikipedia 維基百科

這是名氣很大的跨平台遊戲引擎,構建於 SDL(Simple DirectMedia Layer)之上。

它起先是用來替代終止開發的 pySDL,包含了圖像和音頻的庫。

Cocos2d

Home:http://cocos2d.org/

它是一個開源的 2D 遊戲框架,最初使用 Python 編寫的。後來該框架已經被移植到了多種語言和平台上。

其功能包括了:GUI 組件、音效、物理引擎、腳本語言綁定、場景編輯器 ...

很多手機遊戲是基於 Cocos2d 的衍生框架開發的。

Blender Game Engine

Home:http://www.blender.org/

Links:Wikipedia 維基百科

它是 Blender 的組成部分,雖然是以 C++ 編寫,但內置了 Python 腳本的擴展。

其功能包括:3D 渲染、碰撞檢測、角色編輯器、音效、網路通訊、AI ...

11.2 3D 渲染引擎

PyOpenGL

Home:http://pyopengl.sourceforge.net/

封裝 OpenGL 的 Python 庫。

Python-Ogre

Home:http://www.python-ogre.org/

封裝 OGRE 的 Python 庫。

12 數值計算 科學計算

NumPy

Home:http://www.numpy.org/

Links:Wikipedia 維基百科

它提供了功能強大、性能很高的數值數組,可以用來進行各種數值計算(包括矩陣運算)。

代碼示例

# 以下是傳統 Python 寫法,冗長且速度較慢
a = range(10000000)
b = range(10000000)
c = []
for i in range(len(a)) :
c.append(a[i] + b[i])

# 以下是 NumPy 的寫法,簡潔且速度飛快
import numpy as np
a = np.arange(10000000)
b = np.arange(10000000)
c = a + b

SciPy

Home:http://www.scipy.org/

Links:Wikipedia 維基百科

它依賴 NumPy 提供的多維數組。相比 NumPy,它提供了更高層的數學運算模塊(統計、線性代數、積分、常微分方程求解、傅立葉變換、信號處理 ...)。

它被廣泛用於科研和工程領域。

SymPy

Home:http://sympy.org/

Links:Wikipedia 維基百科

它是用來做符號計算的,其目標是成為一個全功能的「計算機代數系統」。

它支持的功能包括:符號計算、高精度計算、模式匹配、繪圖、解方程、微積分、組合數學、離散數學、幾何學、概率與統計 ......

13 (其它)

一些不方便歸類的,暫時放到這裡。

PyPy

Home:http://www.pypy.org/

Links:Wikipedia 維基百科

它是一個用 Python 寫的 Python 解釋器(有點繞口令)。

PyPy 支持 JIT(Just-in-time compilation)和沙箱技術,可做到【比 CPython 更快的運行速度】。


個人認為 Pythonic 就是用 Python 的語言特性編寫 Simple Clean 的代碼。
正如上面的童鞋說的,有一定語言基礎的初學者容易將 Python 代碼寫成其他語言風格的代碼。
例如下面的代碼是很容易出現在他們之間的:

words = ["This", "is", "an", "example"]
sentences = ""
for word in words:
sentences += word + " "
sentences = sentences[:-1]

實際上只需要:

words = ["This", "is", "an", "example"]
sentences = "".join(words)

是不是更 Simple Clean..
更典型的還有:

foo = "bar"
if foo == "bar1" or foo == "bar2" or foo == "bar3":
pass

可以:

foo = "bar"
if foo in ("bar1", "bar2", "bar3"):
pass

更多的內容可以參考:https://speakerdeck.com/dreampuf/pythonic

然後回答題主的問題。
Pythonic 的源碼,推薦閱讀 mitsuhiko (Armin Ronacher) 路 GitHub 大神的源碼。


初學Python才應該按照Pythonic的風格來寫Python,這樣一開始的習慣就是好的。如果一開始習慣就不好,就像游泳一開始學會了狗刨,以後再回來就得費更多功夫了。

這裡推薦下我寫的有關Pythonic一篇blog,讓你的python代碼更加pythonic,裡面有將近十個code snippet來對比Pythonic和非Pythonic的代碼,文章後還有附有很多關於Pythonic的中英文資料。


推薦閱讀 requests 和 flask的源碼,這也是我一直想看的


我一直很好奇的是,初學者為什麼要讀源碼呢?


首先,體會Pythonic:熟讀PEP-8;
然後,... ...
等等,你說看源碼?《Learning Python》看完沒?《Python Cookbook》看到哪兒了?
看完您可以再回來提問——《如何在項目中寫出Pythonic代碼?》
所以,我的意思是,看代碼不是看小說,閱讀不會帶來長久的愉悅♂,你得寫,按你對Pythonic代碼的認識來寫,然後對比大神們的處理來發現自己的疏漏啥的。
以上。
_____________________
謝江左邀請。


很喜歡Tornado的代碼結構和風格.


python被創造出來的時候是為了讓人們Pythonic,還是為了完成任務啊?


Python 好代碼很多,關鍵是如何讀,& 這本書里第五章有講解如何讀一個命令行工具,如果讀一個大型項目,如果讀一個庫等等,非常好,作者是人生贏家 Kenneth。


GitHub - wangshunping/read_requests: python requests 源碼閱讀,學習更pythonic 的python代碼寫法。
最近在看 requests 的源碼,非常高興能把它分享出來給大家。

也歡迎大家貢獻。

當然最歡迎 star 我啦~~


初學者?請參考這個學習步驟! -&> The Best Way to Learn Python
不謝!


推薦讀讀web.py 的源代碼

https://github.com/webpy/webpy/blob/master/web/utils.py


既然是初學,考慮什麼Pythonic呀,先把代碼寫溜了再說,看別人的源代碼都不順溜,還搞什麼pythonic,熟練以後再改也不習慣也不難。

個人觀點,最容易讓代碼漂亮的方法縮進,但這對python來說根本就不是個事兒。

我恨沒有縮進的代碼。


我覺得只有面對一個問題時才能真正學會一種技能,我是從Django入手去使用python的,框架全面,更新快,文檔全面,同時我的確面臨著一個項目,這樣就從來沒有感到枯燥過。至少是否很pythonic,我覺得都是需要慢慢改進的,解決同一個問題,SO上有不同的答案,github上有不同的第三方模塊,慢慢就變得比較規範了。我現在只用python做過web開發,因為我面臨這個任務,也有這個興趣,所以學習動力就很足。所以,要想變得pythonic,得找到一個適合python的項目。


推薦閱讀:

Python 有哪些好的學習資料或者博客?
相比於 Django、Pylon 等 Python 框架,Ruby on Rails 是否有很大的技術優勢?
TensorFlow 如何入門?
可以用 Python 編程語言做哪些神奇好玩的事情?
Python 的練手項目有哪些值得推薦?

TAG:Python | Python 入門 | Pythonic |