StringToDict and DictToString

K

Kamilche

I made this tonight, after discovering how bad it is to use eval() in
a server program. If someone knows of a better method, let me know!

import types

'''
Convert a string to a dict, or a dict to a string.
Not that comprehensive - it only handles strings, ints,
longs, floats, and None, but it's safer than using 'eval'
and trying to restrict the execution environment!
--Kamilche

Sample output:
--------------
orig dict: {'int': 1, 'none': None, 'float': 1.0,
'string': 'string', 'long': 12345678901234567890L}
to string: ' int 1 none None float 1.0 string string long
12345678901234567890'
to dict: {'int': 1, 'none': None, 'float': 1.0,
'string': 'string', 'long': 12345678901234567890L}

'''

def StringToDict(s):
'''
Convert a string to a dict.
The first char of the string is the delimiter for the items.
Try to parse it, and on failure, return an empty dict.
'''
if type(s) != types.StringType:
raise Exception("Arg to StringToDict must be a string!")
try:
if len(s) < 4:
return {}
delim = s[0]
tokens = s.split(delim)
i = 1
max = len(tokens) - 1
d = {}
while i < max:
key = tokens
value = StringToValue(tokens[i + 1])
d[key] = value
i += 2
return d
except:
return {}

def DictToString(d, delim = '\t'):
'''
Convert a dict to a string. If the str() of any key or value
in the dict contains the delimiter, raise an error. Otherwise,
insert the delimiter into the first character of the string.
'''
tokens = []
if type(d) != types.DictType:
raise Exception("Argument must be a dict!")
if len(d) == 0:
return ''
if len(delim) != 1:
raise Exception("Delimiter must be a single character!")
tokens.append('')
for key, value in d.items():
key = str(key)
value = str(value)
if delim in key or delim in value:
raise Exception("Pick a different delimiter for
DictToString, your data uses %s!" % delim)
tokens.append(key)
tokens.append(value)
return delim.join(tokens)

def StringToValue(s):
" Convert a string to the 'best guess' type"
if type(s) != type(""):
return s
if len(s) == 0:
return s
if s in ('None', 'none'):
return None
if (s[0] in "+-0123456789.") and ("." in s):
try:
v = float(s)
return v
except:
pass
if s[0] in "+-0123456789":
try:
v = int(s)
return v
except:
try:
v = long(s)
return v
except:
pass
return s

def test(**d):
print "orig dict:", d
s = DictToString(d, ' ')
print "to string: '" + s + "'"
print "to dict: ", StringToDict(s)
print

def main():
test()
test(string = 'string', int = 1, float = 1.0, long =
12345678901234567890, none = None)

if __name__ == "__main__":
main()
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top