Reputation: 133
I have an 3rd party python method (ANSA) that returns strings based on user gui input with default values to start with.
The default values may look like this and are stored in a dictionary:
Label Value
Userdata1 123
Userdata2 'abc'
Userdata3 123.456
... ...
Now, these are all returned as a dictionary with string values by the 3rd party "back_box" function.
Is it, based on the class of the default values, possible to change the new string class back to the default classes? Here is something that may make it a bit clearer:
data = {'Userdata1':123,
'Userdata2':'abc',
'Userdata3':123.456}
new_data = black_box(data) # Outputs dictionary with the values as strings
for i, var_name in enumerate(data):
original_class = type(data[var_name])
new_data[var_name] = new_data[var_name].StrToClass(original_class)
So what i am looking for is a method/function/magic trick called strToClass in the above example.
I know it may be a risky way to do it, but any ideas about pythonic ways to do it?
(python3 btw)
Upvotes: 3
Views: 144
Reputation: 23624
Never name a variable def
For complicated classes you'll need more work, however this should do nicely for basic types, and types that have a representation identical to other basic types
d = {'Userdata1':123,
'Userdata2':'abc',
'Userdata3':123.456}
# create a list containing each type
var_type = [ type(d[key]) for key in sorted(d.keys())]
d = black_box(d)
import ast
for vt, key in zip(var_type, sorted(d.keys())):
# if the variable was a string you're already done
if not vt == str:
# cast from string to generic type
d[key] = ast.literal_eval(d[key])
# cast from generic to original type
try:
d[key] = vt(d[key])
except:
print "Error converting dictionary value with key: " + key
print "Unable to cast {} as {}".format(d[key], vt)
Upvotes: 1
Reputation: 1613
I believe the magic function you're looking for is ast.literal_eval.
for i, var_name in enumerate(data):
new_data[var_name] = ast.literal_eval(new_data[var_name])
Upvotes: 1
Reputation: 8326
Just keep the types of the original values of the dictionary in a separate new dictionary, then use that dictionary to transform them back --
>>> my_dict = {'Userdata1':123,
'Userdata2':'abc',
'Userdata3':123.456}
>>> type_dict = {k:type(v) for k,v in my_dict.iteritems()}
>>> type_dict
{'Userdata2': <type 'str'>, 'Userdata3': <type 'float'>, 'Userdata1': <type 'int'>}
>>> str_dict = {k:str(v) for k,v in my_dict.iteritems()}
>>> str_dict
{'Userdata2': 'abc', 'Userdata3': '123.456', 'Userdata1': '123'}
>>> new_dict = {k:type_dict[k](v) for k,v in str_dict.iteritems()}
>>> new_dict
{'Userdata2': 'abc', 'Userdata3': 123.456, 'Userdata1': 123}
Or, using your pseudocode
for i, var_name in enumerate(data):
original_class = type(data[var_name])
new_data[var_name] = original_class(new_data[var_name])
Upvotes: 1