проверка типов для math.isclose () - PullRequest
3 голосов
/ 09 октября 2019

В основном я получил предупреждение ниже в PyCharm в заявлении math.isclose(a_val, b_val)

Expected type 'SupportsFloat', got 'Number' instead

Минимальный, воспроизводимый пример, как показано ниже.

from numbers import Number
import math

a_val = '123'
b_val = 123.4

if isinstance(a_val, Number) and isinstance(b_val, Number):
    is_close = math.isclose(a_val, b_val, abs_tol=0.5)

В действительности, a_val и b_val получены где-то еще, что может вернуть число с плавающей запятой, целое число или строку. Если оба значения a_val и b_val являются числовыми, я хочу проверить, являются ли они почти равными. В противном случае просто игнорируйте его, если какой-либо из них является строкой.

Вопрос - как лучше всего проверять тип перед передачей a_val и b_val в math.isclose()? Какие изменения нужно сделать, чтобы очистить PyCharm Wringing?

Ответы [ 2 ]

2 голосов
/ 09 октября 2019

Ваше решение с проверкой isinstance(a_val, Number) было близко. Вам просто нужно изменить Number на Real из модуля numbers. Действительные числа поддерживают преобразование в число с плавающей точкой, поэтому этот тип проверки является правильным. И предупреждение исчезло. Полный пример кода:

from numbers import Real
import math

a_val = '123'
b_val = 123.4

if isinstance(a_val, Real) and isinstance(b_val, Real):
    is_close = math.isclose(a_val, b_val, abs_tol=0.5)
2 голосов
/ 09 октября 2019

math.isclose не поддерживает произвольных Number экземпляров. Как и большинству math функций, math.isclose нужны аргументы, которые можно преобразовать в float. Number может быть чем-то вроде 1+2j, который не может быть преобразован в float. (Кроме того, str не в счет - это должно быть что-то с __float__ методом.)

Я собирался предложить использовать typing.SupportsFloat, но похоже, что я неправильно прочитал код, иtyping.SupportsFloat не поддерживает isinstance проверки. Если ваши единственные варианты - str, float и int, вероятно, проще всего просто проверить float и int или пойти другим путем и просто отклонить str:

if isinstance(a_val, (float, int)) and isinstance(b_val, (float, int)):
    ...

или

if not isinstance(a_val, str) and not isinstance(b_val, str):
    ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...