Try parse date from string. If None template matching this datestr, 
        raise Error.
         
        :param datestr: a string represent a date
        :type datestr: str
        :return: a datetime.date object
        
        Usage::
        
            >>> from weatherlab.lib.timelib.timewrapper import timewrapper
            >>> timewrapper.str2date("12/15/2014")
            datetime.date(2014, 12, 15)
        
        **中文文档**
        
        尝试从字符串中解析出datetime.date对象。每次解析时, 先尝试默认模板, 如果
        失败了, 再重新对所有模板进行尝试; 一旦尝试成功, 这将当前成功的模板保存
        为默认模板。这样使得尝试的策略最优化。

def str2date(self, datestr):
        """Try parse date from string. If None template matching this datestr, 
        raise Error.
         
        :param datestr: a string represent a date
        :type datestr: str
        :return: a datetime.date object
        
        Usage::
        
            >>> from weatherlab.lib.timelib.timewrapper import timewrapper
            >>> timewrapper.str2date("12/15/2014")
            datetime.date(2014, 12, 15)
        
        **中文文档**
        
        尝试从字符串中解析出datetime.date对象。每次解析时, 先尝试默认模板, 如果
        失败了, 再重新对所有模板进行尝试; 一旦尝试成功, 这将当前成功的模板保存
        为默认模板。这样使得尝试的策略最优化。
        """
        try:
            return datetime.strptime(
                    datestr, self.default_date_template).date()
        except: # 如果默认的模板不匹配, 则重新尝试所有的模板
            pass
        
        # try all date_templates
        # 对每个template进行尝试, 如果都不成功, 抛出异常
        for template in self.date_templates: 
            try:
                a_datetime = datetime.strptime(datestr, template) # 如果成功了
                self.default_date_template = template # 保存为default
                return a_datetime.date()
            except:
                pass
        raise NoMatchingTemplateError(datestr)