Почему ureg (0) равен 1? - PullRequest
       20

Почему ureg (0) равен 1?

0 голосов
/ 05 октября 2018

Следующий код выводит «1 безразмерный»:

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

Почему, Пинта?

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

выглядит как ошибка / ограничение в пакете.

При передаче целого числа (отличается от 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'

in 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")
0 голосов
/ 05 октября 2018

«Вызов» объекта UnitRegistry эквивалентен вызову parse_expression для него .parse_expression ожидает получения str, и у него есть специальный регистр для пустой строки, который должен возвращать ее как Quantity(1) (1 dimensionless вы видите).

В этом случае вы случайно обнаружили незначительный недостаток при наборе утки: она ожидает строку, но на самом деле не проверяет, что она его получила.Затем преобразует любое ложное значение в Quantity(1) с кодом:

if not input_string:
    return self.Quantity(1)

, поэтому любое нулевое число (или None, или пустая последовательность, или другая ложная вещь)становится Quantity(1).Если бы вы передали ему истинное выражение неожиданного типа, парсер был бы вовлечен и вызвал исключение, но ложные значения даже не достигли парсера.

Мне не ясно, почему пустое выражение должно бытьa Quantity(1), но авторы явно поставили эту проверку там, поэтому она должна была быть задана.

Короче говоря, не передавайте не-строки в функцию.Они молча терпят неудачу при ложном срабатывании и выдают исключение для чего-либо еще (когда он предполагает, что они str и пытается вызвать для них str методы).

...