In this question "unit(s)" refers to "unit(s) of measure" used in physical quantities.
I want to safely parse an untrusted user input string containing physical quantities (e.g. '23 kg'). I'd like to use one of the packages available for Python (like Unum or Quantities), because they take care of conversions between units, simplification of units contained in mathematical expression, reduction to base units, but I could not find a way to convert a string to an object (of the aforementioned packages) other than using eval()
, which seems unsafe.
For example, assuming that kg
and cm
are bound to Unum package objects and refer to the kilogram and centimetre units, I need a function capable of returning an Unum package object from a string, something like:
cast_to_unit("100 kg/cm")
or
"100 kg/cm".asUnit()
- Is there a way to obtain such functionality from one the mentioned packages? And if not,
- Is there a way to safely use
eval()
? And if not, - Is there any other package (even not in Python) having such functionality?
You can write something yourself, overloading the operators like that:
Then you could use
eval()
to evaluate expressions (like "100*kg
"), but be careful about it. Probably this should help you get rid of some of the problems:Taking a quick look at
Unum
's documentation, it appears that you should be able to do something like this witheval
:If you do this though, make sure that you read the documentation on
eval
and how you can pass local and global mappings in order to restrict the namespace access to make it safer -- especially if you ever plan on releasing this code to the outside world. You'll probably also want to check the strings for underscores (_
) and not allow those to be passed toeval
.As noted by kindall, importing
*
is usually not good style. Here's a slightly more safe alternative which avoids importing from*
:Note that I cut out the
__
methods as advocated in this post