Python – Use eval() to create numpy.float64

Use eval() to create numpy.float64… here is a solution to the problem.

Use eval() to create numpy.float64

I looked around and didn’t find any informative feature to create numpy.float64 with the built-in eval.

What I want is this:

In [1]: x = eval("1.0")
In [2]: type(x)
Out[2]: <type 'float'>

to:

In [1]: x = eval("1.0")
In [2]: type(x)
Out[2]: <type 'numpy.float64'>

The real problem is worse than the simple example above, because the parameters passed to eval are usually dictionaries with many keys and values. So it’s impossible to use something like numpy.float64("1.0"

).

To give you the concrete real data I’m working on, here’s what a string looks like (it’s read from a file):

data_str = '{"var_x": {"value": 1.23, "error": 0.25, "unit": "unit name"},
            "var_y": {"value": 1e+4, "error": 1.3e1, "log": False},
            "var_z": ["a", {"x":1, "y":2}, (1, 2, 3), None]'
data = eval(data_str)

Then, I want type(data["var_x"]["value"]) to return <type 'numpy.float64'>

Do you have any suggestions? Am I missing an obvious method?


Edit

I will process numbers in data_str with no more precision than 15-16 bits.
So it doesn’t matter if you convert a string to float or numpy.float64 just for that purpose. However, these values will be passed to some complex functions, multiplication, division… So to avoid any error propagation, I have to use numpy.float64.
One workaround is to convert (after eval) any float to numpy.float64, but it’s better to use eval for direct interpretation

Edit #2

I wonder why this doesn’t work :

In [1]: import numpy as np
In [2]: x = eval("1.4", {"__builtins__":None, "np":np}, {"float":np.float64})
In [3]: type(x)
Out[3]: <type 'float'>

I

want to define “__builtins__” as None in eval globals would avoid loading the default definition of float, I redefined in local… It seems impossible to take (or replace) built-in type namespaces (like float, int…) out of eval. Any suggestions on this are welcome 🙂

Solution

What you can do is copy what ast.literal_eval() does, but you can inject the call to the numpy.float64 constructor first instead of just executing the AST.

Related Problems and Solutions