以下代码显示“ 1无量纲”:
import pint
ureg=pint.UnitRegistry()
print(ureg(0.))
为什么要品脱?
答案 0 :(得分:2)
“调用” UnitRegistry
对象is equivalent to calling parse_expression
on it。 parse_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")