Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find which other python types can an object be converted to?

Tags:

python

As a simple example, assume a utility method, which accepts a python object input_obj, and out_type,a python type to convert (typecast) the object into

def convert_obj(input_obj,out_type):

-Examples

convert_obj('2','int')
#returns 2
convert_obj([1,2,3],'tuple')
#returns (1,2,3)

The method only supports objects of specific types like str,list,tuple, and then checks if that can be converted to the out_type specified. This is the rulebook present in the method:

 supported_conversions = {
       tuple: [str, list, set],
       str: [tuple, float, list, long, int, set],
       float: [str, long, int],
       list: [tuple, str, set],
       long: [str, float, int],
       dict: [tuple, str, list, set],
       int: [str, float, long],
       set: [tuple, str, list],

    }

The keys in the supported_conversions are the allowed types for input_obj.

Question : Apart from using try/except over a list of all possible python types to convert a sample object of each type, and then seeing what are valid, e.g. checking str conversion against [list,dict,tuple,int,tuple,set] is there a better way in python to generate the dict supported_conversions, given its keys ?

Note : Other exception on type conversion are to be ignored. e.g "1" can be converted to integer 1,but "XYZ" cannot be. But this still means str->int is a valid possible conversion.

like image 849
DhruvPathak Avatar asked Jan 07 '16 10:01

DhruvPathak


1 Answers

I think the problem space is not well-defined enough for such a method to exist. Some conversions will be destructive, and some could take place in more than one way. A few examples:

>>> list(set([1,2,2,3]))
[1, 2, 3]
>>> list("hello")
['h', 'e', 'l', 'l', 'o']
>>> ["hello"]
['hello']
>>> list({'a':1, 'b': 2})
['a', 'b']
>>> list({'a':1, 'b': 2}.iteritems())
[('a', 1), ('b', 2)]

For the sake of the argument, you can also convert a string to basically any Python type, by using eval().

So, basically, it all depends on your use case.

If you really want to do a more exhaustive search, you can use the types module to get a list of built-in types, and then try to cross-convert (assuming you can get instances of each of these):

>>> import types
>>> [types.__dict__.get(t) for t in dir(types) if t.endswith('Type')]
[<type 'bool'>, <type 'buffer'>, <type 'builtin_function_or_method'>, <type 'builtin_function_or_method'>, <type 'classobj'>, <type 'code'>, <type 'complex'>, <type 'dictproxy'>, <type 'dict'>, <type 'dict'>, <type 'ellipsis'>, <type 'file'>, <type 'float'>, <type 'frame'>, <type 'function'>, <type 'generator'>, <type 'getset_descriptor'>, <type 'instance'>, <type 'int'>, <type 'function'>, <type 'list'>, <type 'long'>, <type 'member_descriptor'>, <type 'instancemethod'>, <type 'module'>, <type 'NoneType'>, <type 'NotImplementedType'>, <type 'object'>, <type 'slice'>, <type 'str'>, <type 'traceback'>, <type 'tuple'>, <type 'type'>, <type 'instancemethod'>, <type 'unicode'>, <type 'xrange'>]

I don't know if you need to generate your supported_conversions dictionary beforehand, though. Assuming you always convert intype to outtype by outtype(intype_value), you can attempt that and then update a dictionary that maps (intype, outtype) -> bool, and so it won't attempt the conversion again if it failed the first time.

like image 161
Vlad Avatar answered Oct 14 '22 07:10

Vlad