Ошибка использования операторов в аргументах функции (isinstance) в Python - PullRequest
0 голосов
/ 27 июня 2018

Я не могу обернуть голову вокруг вывода этой функции:

def is_integer(num1, num2):
        if isinstance(num1 and num2, int):
            return 'Yes'
        else:
            return 'No'

print(is_integer(1.4, 2))

Будет выведено «Да», но это не должно быть, поскольку 1.4 и 2 не являются целыми числами. Любая помощь?

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

Способ работы оператора and в Python:

Выражение x and y сначала оценивает x; если x равно false, возвращается его значение; в противном случае y вычисляется и возвращается полученное значение.

В Python None, False, числовые нули и пустые коллекции являются ложными; почти все остальное верно. 1

Итак, 1.4 and 2 означает 2, потому что 1.4 не ноль.

Итак, isinstance(1.4 and 2, int) означает isinstance(2, int).

И 2 - это int.


Что вы, вероятно, хотели здесь:

if isinstance(num1, int) and isinstance(num2, int):

… или:

if all(isinstance(num, int) for num in (num1, num2)):

1. Чтобы избежать путаницы между конкретными значениями True и False и более абстрактной идеей значений true и false, большинство разработчиков Python именуют None / False / zero / empty как «falsey», а не «false» и все остальное как "правдивое", а не "правдивое". Но документация избегает этой привлекательности, и я цитирую документы здесь.

0 голосов
/ 27 июня 2018
isinstance(num1 and num2, int)

То же, что и

t1 = num1 and num2
if isinstance(t1, int)

Результат двух чисел и между ними возвращает первое значение Falsy, если оно есть, иначе возвращает последнее значение в выражении.

Некоторые примеры:

In [24]: 1.4 and 2
Out[24]: 2

In [25]: 1.4 and 2 and 3
Out[25]: 3

In [26]: 1.4 and 0 and 2
Out[26]: 0

Для получения дополнительной информации см. Странное использование операторов "и" / "или" .


Если вы хотите проверить оба, вы должны сделать их отдельно:

def is_integer(num1, num2):
    if isinstance(num1, int) and isinstance(num2, int):
        return 'Yes'        
    return 'No'

Какой самый странный способ написания

def is_integer(num1, num2):
    if all(isinstance(n, int) for n in (num1, num2)):
        return 'Yes'        
    return 'No'

... с функцией all, которая обобщает до более чем двух аргументов.

Еще лучше, пусть ваша функция принимает переменное число аргументов:

def is_integer(*args):
    if all(isinstance(n, int) for n in args):
        return 'Yes'
    return 'No'

Еще лучше, вернуть логический результат:

def is_integer(*args):
    return all(isinstance(n, int) for n in args)
...