为什么ureg(0)等于1?

时间:2018-10-05 19:12:25

标签: python pint

以下代码显示“ 1无量纲”:

import pint
ureg=pint.UnitRegistry()
print(ureg(0.))

为什么要品脱?

2 个答案:

答案 0 :(得分:2)

“调用” UnitRegistry对象is equivalent to calling parse_expression on itparse_expression expects to receive a str, and it has a special case for the empty string, which is to return it as a Quantity(1)(您看到的1 dimensionless)。

在这种情况下,您碰巧遇到了鸭子输入中的一个小缺陷:它期望一个字符串,但实际上并没有验证它是否收到了一个字符串。然后用代码it converts any falsy value to Quantity(1)

if not input_string:
    return self.Quantity(1)

,因此任何零值数字(或None,空序列或其他虚假事物)都将成为Quantity(1)。如果您将它传递给了一个意外类型的真实表达式,则解析器会参与其中并引发一个异常,但虚假值甚至不会到达解析器。

我不清楚为什么空表达式应该是Quantity(1),但是作者明确地将该检查放在了其中,因此一定是有意的。

简而言之,不要将非字符串传递给该函数。错误时,它们将默默地失败,并引发其他任何异常(当假定它们是str并尝试对它们调用str方法时)。

答案 1 :(得分:2)

看起来像软件包中的错误/限制。

传递整数(不同于0时)pint会导致崩溃:

>>> ureg(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python34\lib\site-packages\pint\registry.py", line 837, in parse_expression
    input_string = string_preprocessor(input_string)
  File "C:\Python34\lib\site-packages\pint\util.py", line 579, in string_preprocessor
    input_string = input_string.replace(",", "")
AttributeError: 'int' object has no attribute 'replace'

registry.py

def parse_expression(self, input_string, case_sensitive=True, **values):
    """Parse a mathematical expression including units and return a quantity object.

    Numerical constants can be specified as keyword arguments and will take precedence
    over the names defined in the registry.
    """

    if not input_string:
        return self.Quantity(1)

    input_string = string_preprocessor(input_string)  # should not be called with something else than string

它崩溃,因为程序包试图在非字符串(期望有字符串)上执行字符串操作。但是测试是if not input_string,因此0.0使pint创建一个1类(或任何意味着),就像您通过""一样。传递1可以到达下一行,该行将崩溃。

它只是缺少类型检查,例如:

    if not isinstance(input_string,str):
        raise Exception("a string is required")