Python, сравнивающий boolean и int с использованием isinstance
Может ли кто-нибудь объяснить мне, почему isinstance()
возвращает True в следующем случае? Я ожидал False, когда писал код.
print isinstance(True, (float, int))
True
Мое предположение заключалось бы в том, что его внутренний подкласмент python, как ноль, так и один - float float или int - оба оцениваются при использовании в качестве логического, но не знают точной причины.
Каким будет самый питонический способ решить такую ситуацию? Я мог бы использовать type()
, но в большинстве случаев это считается менее pythonic.
Ответы
Ответ 1
По историческим причинам bool
является подклассом int
, поэтому True
является экземпляром int
. (Первоначально Python не имел типа bool, а возвращаемые значения истинности возвращались 1 или 0. Когда они добавили bool
, True и False имели для замены на 1 и 0 как можно больше для обратной совместимости, следовательно, для подкласса.)
Правильный способ "решить" это зависит от того, что вы считаете проблемой.
- Если вы хотите
True
перестать быть int
, ну, слишком плохо. Это не произойдет.
-
Если вы хотите обнаружить логические значения и обрабатывать их по-другому от других int, вы можете сделать это:
if isinstance(whatever, bool):
# special handling
elif isinstance(whatever, (float, int)):
# other handling
-
Если вы хотите обнаружить объекты, чей конкретный класс точно равен float
или int
, отклоняя подклассы, вы можете сделать это:
if type(whatever) in (float, int):
# Do stuff.
- Если вы хотите обнаружить все поплавки и ints, вы уже это делаете.
Ответ 2
Если вы хотите проверить только int
:
if type(some_var) is int:
return True
else:
return False
Ответ 3
Да, это правильно, это подкласс int, вы можете проверить его с помощью интерпретатора:
>>> int.__subclasses__()
[<type 'bool'>]
Ответ 4
Посмотрите некоторые поведения (не так странно) Python на Bool и Int
>>> 1 == True
True
>>> 0 == False
True
>>> True*5 == 0
False
>>> True*5 == 5
True
>>>
Как взаимозаменяемы они могут быть использованы...!
Из boolobject.h(win py 2.7) я вижу typedef для bool obj. Так что довольно очевидно, что bool унаследовал несколько черт лица int.
#ifndef Py_BOOLOBJECT_H
#define Py_BOOLOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
typedef PyIntObject PyBoolObject;