1 数据清洗
option里面最重要的方法就是parse,在这里,parse函数的一开始就调用了后面的子函数_parse_datetime,_parse_timedelta,_parse_bool,_parse_string。经过我分割,查找具体函数执行情况,这四个函数其实是清理格式的,为了防止格式混乱,导致后期处理困难。就用它们做了格式清洗。
1 def parse(self, value): 2 _parse = { 3 datetime.datetime: self._parse_datetime, 4 datetime.timedelta: self._parse_timedelta, 5 bool: self._parse_bool, 6 basestring_type: self._parse_string, 7 }.get(self.type, self.type) 8 9 注:parse函数的部分内容
(1)时间格式数据清洗
1 # Supported date/time formats in our options 2 _DATETIME_FORMATS = [ 3 "%a %b %d %H:%M:%S %Y", 4 "%Y-%m-%d %H:%M:%S", 5 "%Y-%m-%d %H:%M", 6 "%Y-%m-%dT%H:%M", 7 "%Y%m%d %H:%M:%S", 8 "%Y%m%d %H:%M", 9 "%Y-%m-%d", 10 "%Y%m%d", 11 "%H:%M:%S", 12 "%H:%M", 13 ] 14 15 def _parse_datetime(self, value): 16 for format in self._DATETIME_FORMATS: 17 try: 18 return datetime.datetime.strptime(value, format) 19 except ValueError: 20 pass 21 raise Error('Unrecognized date/time format: %r' % value)
这个列表是有讲究的,从列表顺序自上而下进行匹配。
当匹配成功后,就返回一个标准值。如果匹配失败,就返回一个ValueError。因此,原作者在这里对ValueError做了一个异常处理。
如果全部都匹配失败,那么久返回一个错误,证明时间参数的确有问题了。
以下部分是我做的一个匹配失败报错的情况:
1 >>> datetime.datetime.strptime("19:20:20", "%H:%M") 2 Traceback (most recent call last): 3 File "<stdin>", line 1, in <module> 4 File "C:Python27lib\_strptime.py", line 328, in _strptime 5 data_string[found.end():]) 6 ValueError: unconverted data remains: :20
(2) unix时间模式的数据清洗
我们都知道,程序中表示时间还有一种方式是unix时间戳,大意就是从1970年开始,已经执行的秒数。
这部分,我没有细看,不过简单分析,应该就是时间模式的一个替换
1 _TIMEDELTA_ABBREV_DICT = { 2 'h': 'hours', 3 'm': 'minutes', 4 'min': 'minutes', 5 's': 'seconds', 6 'sec': 'seconds', 7 'ms': 'milliseconds', 8 'us': 'microseconds', 9 'd': 'days', 10 'w': 'weeks', 11 } 12 13 _FLOAT_PATTERN = r'[-+]?(?:d+(?:.d*)?|.d+)(?:[eE][-+]?d+)?' 14 15 _TIMEDELTA_PATTERN = re.compile( 16 r's*(%s)s*(w*)s*' % _FLOAT_PATTERN, re.IGNORECASE) 17 18 def _parse_timedelta(self, value): 19 try: 20 sum = datetime.timedelta() 21 start = 0 22 while start < len(value): 23 m = self._TIMEDELTA_PATTERN.match(value, start) 24 if not m: 25 raise Exception() 26 num = float(m.group(1)) 27 units = m.group(2) or 'seconds' 28 units = self._TIMEDELTA_ABBREV_DICT.get(units, units) 29 sum += datetime.timedelta(**{units: num}) 30 start = m.end() 31 return sum 32 except Exception: 33 raise
(3) bool值的数据清洗
这部分是用一个判断来做的,根据判断结果,自然而然就将不规范的bool值(如true,false)转成规范的bool值了
这里函数我提取出来并测试了一下,是成功的,但是我没有搞明白实际的原理。
1 def _parse_bool(self, value): 2 return value.lower() not in ("false", "0", "f")
(4) 字符串变量的数据清洗
这部分就没啥好说的了,大意就是把str等都转成unicode
1 def _parse_string(self, value): 2 return _unicode(value)