以下代码打印“1无量纲”:
import pint
ureg=pint.UnitRegistry()
print(ureg(0.))
为什么,品脱?
“调用”一个UnitRegistry
对象相当于调用parse_expression
它。parse_expression
期望收到 a str
,并且它有一个空字符串的特殊情况,即将它作为 aQuantity(1)
(1 dimensionless
你看到的)返回。
在这种情况下,您碰巧遇到了鸭子打字的一个小缺陷:它需要一个字符串,但实际上并没有验证它是否收到了一个字符串。然后它将任何虚假值转换Quantity(1)
为代码:
if not input_string:
return self.Quantity(1)
所以任何零值数(或None
,或空序列,或其他虚假事物)变为Quantity(1)
。如果你向它传递了一个意外类型的真值表达式,解析器就会介入并引发异常,但假值甚至永远不会到达解析器。
我不清楚为什么空表达式应该是 a Quantity(1)
,但作者明确地将检查放在那里,所以它一定是有意的。
简而言之,不要将非字符串传递给函数。它们会在 falsy 时默默地失败,并为其他任何东西引发异常(当它假设它们是 astr
并尝试调用它们的str
方法时)。
看起来像包中的错误/限制。
传递整数(不同于 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")