4

This is a problem I am facing for a data pipeline project. I have 2 data sources. One contains all the user data, the other contains meta data of what all columns we have to process from the user data to output.

So python is good with dynamic type casting, like if I say

a = float
b = "25.123"
c = a(b)
print(c)
>> 25.123

This is what I want to do, I want to dynamically type cast values in order to process them correctly. The type is retrieved from the meta-data data source. The problem is when I do a django model query on the meta-data, I get unicode objects.

a = model.objects.filter(id = 'id') # get the type variable from the meta-data
a = a[0]['type']
print(a)
>> u'float'
a("123.123")
>> TypeError: 'unicode' object is not callable

How do I convert this u'float' to float ? Does this approach have any better alternatives ? I checked out this, but it does not work

Open to all suggestions

1
  • 3
    I would create an explicit mapping from strings to types. Commented May 3, 2018 at 6:50

3 Answers 3

7

In your first example where a = float, a is a built in function, but in your second example, a = u"float", a is an unicode string. If you want complete "dynamicness" of the built in type to convert to without the need of creating a mapping, you can do this:

# for Python 2
a = u"float"
b = "123.123"
import __builtin__
print getattr(__builtin__, a.decode())(b) 
# 123.123

# for Python 3+
a = u"float"
b = "123.123"
import builtins
print(getattr(builtins, a)(b))
# 123.123

I would advise you not to use eval() (as suggested by another answer) because it could lead to major security risks. This is why I used the __builtin__/builtins module and getattr() to retrieve the float(...) function.


You may also create a mapping (ie. a dict), to map the unicode string to its corresponding function (suggested by this comment):

# both Python 2 and 3
a = u"float"
b = "123.123"
mapping = {u"float": float, u"int": int, u"str": str, u"list": list}
print(mapping[a](b))
# 123.123

Using a mapping is the safest way to go, but it limits your "dynamicness" to only the types listed in the mapping.

Sign up to request clarification or add additional context in comments.

2 Comments

how do we do this with date or datetime objects ? suppose a = u"date", getattr will not work there right
understood, so instead of using builtin, you use datetime
0

You may use the eval() function to evaluate the code, but you need to be careful with that function! Otherwise, you might have a look at that post. Another solution is to pre-define allowed types and gather them inside a dictionary mapping typeName with typeConstructor.

2 Comments

better to have a predefined dict mapped, eval() may lead to problems in the future
Yes, that's why I emphasize the fact that it is needed to be careful. Many security flaws may appear, so I actually won't recommend eval() but that was the first that came to my mind.
0

You could use astype from the numpy library:

import numpy as np
np.array(('213.123')).astype(a)

admittedly, this needs to go via an array, because astype() works on numpy-arrays - but it can compute a string as type.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.