Comparing boolean and int using isinstance

Can someone give me an explanation why isinstance() returns True in the following case? I expected False, when writing the code.

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

My guess would be that its Python’s internal subclassing, as zero and one – whether float or int – both evaluate when used as boolean, but don’t know the exact reason.

What would be the most pythonic way to solve such a situation? I could use type() but in most cases this is considered less pythonic.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

For historic reasons, bool is a subclass of int, so True is an instance of int. (Originally, Python had no bool type, and things that returned truth values returned 1 or 0. When they added bool, True and False had to be drop-in replacements for 1 and 0 as much as possible for backward compatibility, hence the subclassing.)

The correct way to “solve” this depends on exactly what you consider the problem to be.

  • If you want True to stop being an int, well, too bad. That’s not going to happen.
  • If you want to detect booleans and handle them differently from other ints, you can do that:
    if isinstance(whatever, bool):
        # special handling
    elif isinstance(whatever, (float, int)):
        # other handling
  • If you want to detect objects whose specific class is exactly float or int, rejecting subclasses, you can do that:
    if type(whatever) in (float, int):
        # Do stuff.
  • If you want to detect all floats and ints, you’re already doing that.

Method 2

Yes, this is right, it’s a subclass of int, you can verify it using the interpreter:

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

Method 3

You can see the method resolution order, and find all superclasses from there:

>>> bool.__mro__
(<class 'bool'>, <class 'int'>, <class 'object'>)

Method 4

If you only want to check for int:

if type(some_var) is int:
    return True

else:
    return False

Method 5

See some behaviors (Not so wierd) of python on bool and int

>>> 1 == True  
True           
>>> 0 == False 
True           
>>> True*5 == 0
False          
>>> True*5 == 5
True           
>>>

How interchangeable can they be used…!

From boolobject.h (win py 2.7) I can see a typedef of int for bool obj. So it is pretty evident that bool has inherited few facial features of int.

#ifndef Py_BOOLOBJECT_H
#define Py_BOOLOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif


typedef PyIntObject PyBoolObject;

Method 6

Here is a instance checker that is safe with bool’s and takes single types or tuples of types just like isinstance()

def isInst(o, of) -> bool:
    if o is None: return False
    cls = o.__class__
    if isinstance(of, type):
        return cls == of

    else:
        if cls == bool:
            return bool in of
        else:
            for i in range(len(of)):
                if cls == of[i]: return True

    return False


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x