
urlparse 源码阅读
Table of content:
写这篇文章的初衷是在在使用 urljoin 的过程中,有几次的结果是我始料未及的,比如
1  | from urlparse import urljoin  | 
那么 urljoin 是怎么做的,urlparse 里还有什么其他的 function, 这里面涉及到的类有哪些?因为代码很简单,这篇文章只是一些逻辑分析。
关于 URL 结构
1  | <scheme>://<netloc>/<path>;<params>?<query>#<fragment>  | 
- scheme, URL 使用的协议, 比如 HTTP, HTTPS, FTP
 - netloc, Network Location Part, 在 RFC 里面提到的是在 
//后面正式引入的才是 netloc, 比如urlparse('www.cwi.nl/%7Eguido/Python.html')parse 出来的 netloc 是''而 path 是'www.cwi.nl/%7Eguido/Python.html' - username, password, host, port, path 对照上面的结构其实很清晰了。
 - parameters, 用 
;分隔出来的 kv,使用的场景非常少, 在 RFC 里面也没有太看出和 query 的使用区别是什么。 - query, 用 
?分隔出来的 kv, - fragment, 用 
#分隔出来的锚点 
主要的类
在 urlparse 中有两个比较关键的类 ParseResult, 和 ResultMixin
ParseResult
1  | class ParseResult(namedtuple('ParseResult', 'scheme netloc path params query fragment'), ResultMixin):  | 
Python 在各个实例中名为 __dict__ 里存储实例属性,为了使用底层的散列表提高访问速度,字典会消耗大量的内存。如果要处理数百万个属性不多的实例,通过 __slots__ 类属性,能节省大量的内存,方法是让解释器在元祖中存储实例属性,而不用字典。
注:
- 继承自超类的 
__slots__属性没有效果,Python 只会使用各个类中定义的__slots__属性 - 实例只能拥有 
__slots__中列出的属性 
ResultMixin
ResultMixin 主要还是在把 netloc 里面的 username,password,host,port 的部分摘取出来
1  | class ResultMixin(object):  | 
这里比较有趣的是 hostname 是全部被处理成小写了。如果这里对大小写敏感,比如是 Mysql 或者 Redis 连接串时,可能就要注意了。
functions
主要的 function 有 urljoin、urlsplit、urlunsplit、urlparse, 这里目前只涉及到 urljoin
urljoin
在 urljoin 的过程中:
- urlsplit 会将传入的两个 URL parse 为 ParseResult 对象
 
1  | bscheme, bnetloc, bpath, bparams, bquery, bfragment = \  | 
- 最近再根据不同的 scheme, 是否有 query,parameter,fragment 等情况将 parse 好的 URL unparse 回去, 返回完整的 URL
 
值得注意的点
- 后一个 url 如果是以 
/开头, 会直接返回后者的 path 
1  | urljoin('http://xxx.test.com/api/v1', '/path/a') # http://xxx.test.com/path/a  | 
- 如果后一个 url 不是以 
/开头,就会对两个 path 进行一些合并, 比如 
1  | urljoin('http://xxx.test.com/api/v1', 'path/a') # http://xxx.test.com/api/path/a  | 
Reference
- URL structure https://www.skorks.com/2010/05/what-every-developer-should-know-about-urls/
 - urlparse 代码 https://github.com/python/cpython/blob/2.7/Lib/urlparse.py#L233:1
 - Fluent Python 9.8 
__slots__ - usage of slots https://stackoverflow.com/questions/472000/usage-of-slots
 - http://book.pythontips.com/en/latest/__slots__magic.html
 
关于头图
- 拍摄自韩国首尔