2016-06-17 3 views
4

Может кто-нибудь дать мне объяснение, почему isinstance() возвращает True в следующем случае? Я ожидал False, когда писал код.python сравнение boolean и int using isinstance

print isinstance(True, (float, int)) 
True 

Мое предположение было бы, что внутренние подклассы своего питона, как ноль и один - Wheter поплавка или INT - как оценить при использовании в качестве булева, но не знают точную причины.

Какой был бы самый питонический способ решить такую ​​ситуацию? Я мог бы использовать type(), но в большинстве случаев это считается менее питоническим.

ответ

13

По историческим причинам bool является подклассом int, поэтому True является примером int. (Первоначально у Python не было типа bool, а вещи, которые возвращали значения истинности, возвращались 1 или 0. When they added bool, True и False должны были быть вставками замены для 1 и 0 как можно больше для обратной совместимости, следовательно, для подкласса.)

Правильный способ «решить» это зависит от того, что вы считаете проблемой.

  • Если вы хотите True перестать быть 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, вы уже это делаете.
+0

Это второй случай. Это означает, что нужно следить за порядком сравнений этих встроенных типов - понятным с учетом наследования, но довольно необычным для python. – jake77

0

Да, это правильно, это подкласс междунар, вы можете проверить его с помощью переводчика:

>>> int.__subclasses__() 
[<type 'bool'>] 
0

Если вы хотите, чтобы проверить int:

if type(some_var) is int: 
    return True 

else: 
    return False