0

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]}
4

0 に答える 0