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
关于头图
- 拍摄自韩国首尔