deserial モジュールが値の型を認識できないことがあります。ネストされた構造で str->int をユニバーサル変換するための関数を検索または作成したい。なんか書いたけど見苦しい。
1アイテムのコンバーター
from decimal import Decimal
def convert_from(s):
if not isinstance(s, basestring):
return s
possible_types = [float, Decimal, int]
if '.' in s:
possible_types.remove(int) # it cannot be!
parts = s.split('.')
if len(parts) > 2:
return s
if len(parts[1]) <= 2:
possible_types.remove(float)
else:
possible_types.remove(Decimal)
possible_types.remove(float)
for convertor in possible_types:
try:
return convertor(s)
except:
pass
return s
ショートカット:
def is_iterable(iterable):
try:
it = iter(iterable)
except:
return False
return True
def process_plain(iterable): # convert a signle list
res = []
for k in iterable:
pk = k
if isinstance(k, basestring):
pk = convert_from(k)
elif is_iterable(k):
pk = convert_all(k)
res.append(pk)
return res
そして最後に:
def convert_all(iterable):
if isinstance(iterable, basestring) or not is_iterable(iterable):
return iterable
keys = list(iterable)
vals = []
if isinstance(iterable, dict):
vals = iterable.values()
processed_keys = process_plain(keys) #[]
processed_vals = process_plain(vals) #[]
if isinstance(iterable, dict):
return type(iterable)(zip(processed_keys, processed_vals))
return type(iterable)(processed_keys)
結果:
d = {
'a': 5,
'2': ['1', 2, '3'],
666: {
'15': 25,
3: '255',
('55',66,'12', '2.00'): 'string',
'nested again': {
5: '12',
'12.12': 5
}
}
}
print convert_all( d )
{'a': 5, 666: {3: 255, 'nested again': {Decimal('12.12'): 5, 5: 12}, (55, 66, 12, Decimal('2.00')): 'string', 15: 25}, 2: [1, 2, 3]}