初衷
最近有個專案,需要處理 URL 地方很多,然 Python 的 url 處理庫真是混亂不堪,我每次都是邊看文件邊寫程式碼的。但是我自己很討厭這種「邊查文件邊寫程式碼」的方式,這種現象基本表示:要麼是你對這門語言不熟悉,要麼是這門語言(庫)的 API 設計不怎麼樣。鑑於自己在大學的時候,就已經拿 Python 來寫東西了,語言使用層面上的東西,已經很熟了,但是仍然每次都會陷入那種「邊查邊寫」的境地,這應該是 API 設計出了問題(嗯,一定是這樣的)。
怎麼說呢,Python 標準庫裡面確實是有幾個設計不佳的,API 命名混亂不堪(小寫+縮寫),而且要精讀文件才能知曉全部意思。我理想中的 API 應該是見名知義的,庫作者要充分理解呼叫者的感受,不應把自己的責任或義務轉嫁到呼叫者身上。(不過說了那麼多,人家的東西能進標準庫就表示他 NB,愛用用,不用滾 :) )
歷史原因也好,大牛牛逼也罷,都與我們沒有關係,我們關心的是:快速且舒服優雅地解決問題。
介面包裝
我們的專案還是使用 Python 2.7,自然面對的就是 urllib/urllib2/urlparse 這幾個庫。Python 3 裡面將這一塊相關的內容重新梳理了一下,API 什麼的也變得清爽了很多。
我的簡單包裝如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
"""對urllib/urllib2標準庫的封裝"""
from __future__ import (absolute_import, unicode_literals)
import urlparse
import urllib
class UrlUtils(object):
"""處理URL的工具函式"""
@classmethod
def remove_fragment(cls, urlstr):
return urlparse.urldefrag(urlstr)
@classmethod
def encode_special_chars(cls, query_str_value):
return urllib.quote(query_str_value)
@classmethod
def decode_special_chars(cls, encoded_chars):
return urllib.unquote(encoded_chars)
@classmethod
def encode_query_dict(cls, query_dict):
return urllib.urlencode(query_dict)
@classmethod
def decode_query_dict(cls, encoded_dict):
return urlparse.parse_qs(encoded_dict)
@classmethod
def get_url_instance(cls, urlstr):
return urlparse.urlparse(urlstr, allow_fragments=True)
複製程式碼
由於我寫 API 一般是「按需寫,用到的時候才寫」,並且「喜歡從原型程式碼裡面提煉出介面,不太喜歡一開始就設計一個巨集偉的藍圖」(能力不行,做不到),所以一般介面的數量也很少。
總結
如前文所述,Python 標準庫裡面確實有設計爛的地方,這一點需要承認。一般來說,如果一個介面在你需要反覆翻閱文件才知道如何使用,那這就是你包裝一下方便自己的時候了。
附錄
- Python 2 標準庫文件
- Python 3 標準庫文件
- Qt API design