ITEEDU

URLopener结构

class URLopener:
   def __init__(self, proxies=None,**x509):
   def __del__(self):
   def close(self):
   def cleanup(self):
   def addheader(self,*args):
   def open(self, fullurl, data=None):
   def open_unknown(self, fullurl, data=None):
   def open_unknown_proxy(self, proxy, fullurl, data=None):
   def retrieve(self, url, filename=None, reporthook=None, data=None):
   def open_http(self, url, data=None):
   def http_error(self, url, fp, errcode, errmsg, headers, data=None):
   def http_error_default(self, url, fp, errcode, errmsg, headers):
   def open_https(self, url, data=None):
   def open_file(self, url):
   def open_local_file(self, url):
   def open_ftp(self, url):
   def open_data(self, url, data=None):

该类的设计逻辑是不管37是否等于21,先实例化该类对象出来,如果有代理,在实例化的时候将代理制定给这个实例化对象的一个属性,然后直接调用这个类的open方法,open方法里面有很多处理逻辑,比如,通过你给定url来判断要使用什么协议来对这个url进行处理,调用本类中的那个方法。

设计中的一个经典核心代码:

        urltype, url = splittype(fullurl)#解析url,分析出该url的特点,比如file,ftp,http,等
        if not urltype:
            urltype = 'file'
        if urltype in self.proxies:
            proxy = self.proxies[urltype]
            urltype, proxyhost = splittype(proxy)
            host, selector = splithost(proxyhost)
            url = (host, fullurl) # Signal special case to open_*()
        else:
            proxy = None
        name = 'open_' + urltype
        self.type = urltype
        name = name.replace('-', '_')
        if not hasattr(self, name):
            if proxy:
                return self.open_unknown_proxy(proxy, fullurl, data)
            else:
                return self.open_unknown(fullurl, data)
        try:
            if data is None:
            	#getattr()方法,如果name(形如'open_http','open_ftp','open_local_file')为真,返回这个属性,
                #即调用了这个方法,并且url是他传入的一个参数!从该类中其他方法名可以看出作者就是这个意思。
                return getattr(self, name)(url)                          
            else:
                return getattr(self, name)(url, data)
        except socket.error, msg:
            raise IOError, ('socket error', msg), sys.exc_info()[2]

调用到符合url协议的方法了,然后就知道识别找方法。