在这个问题中,“单位”是指物理量中使用的“计量单位”。
我希望安全地解析一个不受信任的用户输入字符串,其中包含物理量(例如“23公斤”)。我想使用Python可用的包之一(比如Unum或Quantities),因为它们负责单位之间的转换、数学表达式中包含的单元的简化、对基单元的简化,但除了使用eval()之外,我找不到一种方法将字符串转换为(上述包中的)对象,这似乎不安全。
例如,假设kg和cm绑定到Unum包对象并引用公斤和厘米单位,我需要一个能够从字符串返回Unum包对象的函数,如下所示:
cast_to_unit("100 kg/cm")
或
"100 kg/cm".asUnit()
eval()的方法?如果不是,发布于 2012-11-28 18:40:07
快速查看一下Unum的文档,看起来您应该能够用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。
正如金德尔所指出的,导入*通常不是很好的风格。这里有一个稍微安全一些的替代方案,它避免从*导入
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)注意,我删除了这个__中提倡的帖子方法
发布于 2012-11-28 18:46:02
Note:这不是一个明确的答案。请把它当作一个例子,说明如何构建类似于您所要求的东西。使用
Unum模块确实是一个更好的主意,除非它不适合您的需要。
你可以自己写一些东西,像这样重载操作符:
>>> class Unit(object):
def __init__(self, unit_name):
self.unit_name = unit_name
self.unit_qty = 1
def __div__(self, other):
result = self.__class__(self.unit_name)
result.unit_qty = self.unit_qty / other
return result
def __rdiv__(self, other):
result = self.__class__(self.unit_name)
result.unit_qty = other / self.unit_qty
return result
def __mul__(self, other):
result = self.__class__(self.unit_name)
result.unit_qty = self.unit_qty * other
return result
def __rmul__(self, other):
return self.__mul__(other)
def __repr__(self):
return '%s %s' % (self.unit_qty, self.unit_name)
>>> kg = Unit('kg')
>>> 100 * kg
100 kg
>>> 100 * 10 * kg
1000 kg
>>> (10 * 20 * kg) / 2
100 kg然后您可以使用eval()来计算表达式(如"100*kg"),但是要小心。这可能会帮助您解决一些问题:
eval('100*kg', {'__builtins__': {}, 'kg': Unit('kg')})https://stackoverflow.com/questions/13611851
复制相似问题