首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将字符串转换为Python中的“unit”对象

将字符串转换为Python中的“unit”对象
EN

Stack Overflow用户
提问于 2012-11-28 18:21:17
回答 2查看 992关注 0票数 1

在这个问题中,“单位”是指物理量中使用的“计量单位”。

我希望安全地解析一个不受信任的用户输入字符串,其中包含物理量(例如“23公斤”)。我想使用Python可用的包之一(比如Unum或Quantities),因为它们负责单位之间的转换、数学表达式中包含的单元的简化、对基单元的简化,但除了使用eval()之外,我找不到一种方法将字符串转换为(上述包中的)对象,这似乎不安全。

例如,假设kgcm绑定到Unum包对象并引用公斤和厘米单位,我需要一个能够从字符串返回Unum包对象的函数,如下所示:

cast_to_unit("100 kg/cm")

"100 kg/cm".asUnit()

  1. 是否有办法从上述的包中获得这样的功能?如果不是,
  2. 有没有一种安全使用eval()的方法?如果不是,
  3. 还有其他的包(甚至没有在Python中)具有这样的功能吗?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-11-28 18:40:07

快速查看一下Unum文档,看起来您应该能够用eval做这样的事情。

代码语言:javascript
复制
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

正如金德尔所指出的,导入*通常不是很好的风格。这里有一个稍微安全一些的替代方案,它避免从*导入

代码语言:javascript
复制
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)

注意,我删除了这个__中提倡的帖子方法

票数 5
EN

Stack Overflow用户

发布于 2012-11-28 18:46:02

Note:这不是一个明确的答案。请把它当作一个例子,说明如何构建类似于您所要求的东西。使用Unum模块确实是一个更好的主意,除非它不适合您的需要。

你可以自己写一些东西,像这样重载操作符:

代码语言:javascript
复制
>>> 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"),但是要小心。这可能会帮助您解决一些问题:

代码语言:javascript
复制
eval('100*kg', {'__builtins__': {}, 'kg': Unit('kg')})
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13611851

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档