user2987193
user2987193

Reputation: 133

Python string to other classes

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

Answers (3)

flakes
flakes

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

Peter G
Peter G

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

C.B.
C.B.

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

Related Questions