在这个问题中,“单位”指的是物理量中使用的“计量单位”。
我想安全地解析包含物理量(例如“23 公斤”)的不受信任的用户输入字符串。我想使用 Python 可用的包之一(如 Unum 或 Quantities),因为它们负责单位之间的转换,简化数学表达式中包含的单位,减少到基本单位,但除了使用 eval()
之外,我找不到将字符串转换为(上述包的)对象的方法,这似乎不安全。
例如,假设 kg
和 cm
绑定(bind)到 Unum 包对象并引用千克和厘米单位,我需要一个能够从字符串返回 Unum 包对象的函数,例如:
cast_to_unit("100 kg/cm")
或
"100 kg/cm".asUnit()
- 有没有办法从一个
提到包?如果没有,
- 有没有办法安全使用
评估()
?如果没有,
- 是否还有其他包裹(即使不在
Python)有这样的功能吗?
快速浏览一下 Unum
的 documentation , 看起来你应该能够用 eval
做这样的事情:
from unum.units import * # Load a number of common units.
distance = 100*m
time = eval('9.683*s')
speed = distance / time
print(speed)
如果您这样做,请确保您阅读了有关eval
的文档以及如何传递本地和全局映射以限制命名空间访问以使其更安全——尤其是当您曾经计划向外界发布此代码。您可能还想检查字符串中的下划线 (_
),并且不允许将它们传递给 eval
。
正如 kindall 所指出的,导入 *
通常不是好的风格。这是一个稍微更安全的替代方案,它避免从 *
导入:
import unum.units
safe_dict = dict((x,y) for x,y in unum.units.__dict__.items() if '__' not in x)
safe_dict['__builtins__'] = None
def convert(s):
if '__' in s:
raise ValueError("Won't do this with underscores...it's unsafe")
return eval(s,safe_dict)
请注意,我删除了此 post 中提倡的 __
方法