Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dynamically convert python datatype

Tags:

python

I have a use case where I am reading some data from an API call, but need to transform the data before inserting it into a database. The data comes in a integer format, and I need to save it as a string. The database does not offer a datatype conversion, so the conversion needs to happen in Python before inserting.

Within a config file I have like:

config = {"convert_fields": ["payment", "cash_flow"], "type": "str"}

Then within python I am using the eval() function to check what type to convert the fields to.

So the code ends up being like data['field'] = eval(config['type'])(data['field'])

Does anyone have a better suggestion how I can dynamically change these values, maybe without storing the python class type within a config file.

To add, like sure I could just do str(), but there may be a need to have other fields to convert at some point, which are not string. So I want it to be dynamic, from whatever is defined in the config file for the required conversion fields.

like image 636
dataviews Avatar asked Aug 10 '26 11:08

dataviews


1 Answers

How about using getattr() and __builtins__ that I feel is a little better than exec()/eval() in this instance.

def cast_by_name(type_name, value):
    return getattr(__builtins__, type_name)(value)
print(cast_by_name("bool", 1))

Should spit back:

True

You will likely want to include some support for exceptions and perhaps defaults but this should get you started.

@mistermiyagi Points out a critical flaw that of course eval is a bulitin as well. We might want to limit this to safe types:

def cast_by_name(type_name, value):
    trusted_types = ["int", "float", "complex", "bool", "str"] ## others as needed
    if type_name in trusted_types:
        return getattr(__builtins__, type_name)(value)
    return value
print(cast_by_name("bool", 1))
like image 125
JonSG Avatar answered Aug 12 '26 02:08

JonSG