【转】Python之美[从菜鸟到高手]--urlparse源码分析

urlparse是用来解析url格式的,url格式如下:protocol :// hostname[:port] / path / [;parameters][?query]#fragment,其中;parameters一般用来指定特殊参数,使用的较少,至少我没怎么碰到,举几个链接:http://en.wikipedia.org/wiki/Robotics;Notes,http://en.wikipedia.org/wiki/Awesome;_I_Fuckin%27_Shot_That!


一:urlparse快速使用


    urlparse(url, scheme='', allow_fragments=True):将:///;?#解析成一个6元组:(scheme, netloc, path, params, query, fragment)。返回值是元组,继承自tuple,定义了一些属性,如netloc等。urlunparse是其逆操作。

[python]  view plain  copy
  1. from urlparse import *  
  2. url="http://www.test.com/search?key=python"  
  3. parse=urlparse(url)  
  4. print parse #('http', 'www.test.com', '/search','','key=python', '')  
  5. print parse.netloc #www.test.com  
  6. url2=urlunparse(parse)  
  7. print url2  #http://www.test.com/search?key=python  

     urlsplit(url, scheme='', allow_fragments=True):将:///?#解析成一个5元组:(scheme, netloc, path, query, fragment)。urlunsplit是其逆操作。和urlparse很像,只是少了一个较少适用的参数,urlparse的内部实现就是调用urlsplit,如果url中没有[;parameters],建议使用urlsplit,更明确,更简洁。
[python]  view plain  copy
  1. from urlparse import *  
  2. url="http://www.test.com/search?key=python"  
  3. parse=urlsplit(url)  
  4. print parse #('http', 'www.test.com', '/search','key=python', '')  
  5. print parse.netloc #www.test.com  
  6. url2=urlunsplit(parse)  
  7. print url2  #http://www.test.com/search?key=python  


二:源码分析


     上述两个函数返回的对象都是元组,且都有自己的方法,主要是因为结果集是继承自tuple,代码如下:

[python]  view plain  copy
  1. class BaseResult(tuple):  
  2.     __slots__ = ()  
  3.     @property  
  4.     def scheme(self):  
  5.         return self[0]  
  6.  
  7.     @property  
  8.     def username(self):  
  9.         netloc = self.netloc  
  10.         if "@" in netloc:  
  11.             userinfo = netloc.split("@"1)[0]  
  12.             if ":" in userinfo:  
  13.                 userinfo = userinfo.split(":"1)[0]  
  14.             return userinfo  
  15.         return None  
  16.   
  17.       
  18.   
  19. class SplitResult(BaseResult):  
  20.   
  21.     __slots__ = ()  
  22.   
  23.     def __new__(cls, scheme, netloc, path, query, fragment):  
  24.         return BaseResult.__new__(  
  25.             cls, (scheme, netloc, path, query, fragment))  
  26.   
  27.     def geturl(self):  
  28.         return urlunsplit(self)  
  29.   
  30.   
  31. class ParseResult(BaseResult):  
  32.   
  33.     __slots__ = ()  
  34.   
  35.     def __new__(cls, scheme, netloc, path, params, query, fragment):  
  36.         return BaseResult.__new__(  
  37.             cls, (scheme, netloc, path, params, query, fragment))  
  38.  
  39.     @property  
  40.     def params(self):  
  41.         return self[3]  
  42.   
  43.     def geturl(self):  
  44.         return urlunparse(self)  

    其中SplitResult是urlsplit的返回值,ParseResult是urlparse的返回值,可以看出主要区别还是有无params参数。从这里也可以学习到如何扩展数据结构,tuple接受一个序列作为参数,不止是上述的元组对像,且__new__需要返回构建的对象。我们可以实现自己的扩展元组,接受一list对象。


【转】Python之美[从菜鸟到高手]--urlparse源码分析_第1张图片



   注意一下BaseResult的__slot__用法,__slot__作用是阻止类实例化对象时分配__dict__,而如果有了__dict__,那么随便添加属性就很方便了。BaseResult将__slot__设为空,就是为了随意给返回对象添加属性,而我们刚刚自定义的就不一样。


【转】Python之美[从菜鸟到高手]--urlparse源码分析_第2张图片


我们看看BaseResult,


【转】Python之美[从菜鸟到高手]--urlparse源码分析_第3张图片


三:其它



    urljoin(base, url, allow_fragments=True),合成url函数,还记得项目中是自己写的,汗,这边有现成的。

   urldefrag(url),将url中的fragment去的,即去掉“#”后面的链接。

   _splitnetloc(url, start=0),从url中获取netloc。

    值得说明一点的是整个urlparse模块都没有采用正则去匹配数据,完全是序列话的分析,很值得一看。



写的很好的博客,学到了,转过来马克一下。

你可能感兴趣的:(python基础)