Reputation: 2034
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.
Upvotes: 101
Views: 54610
Reputation: 4485
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
Upvotes: 0
Reputation: 3988
You can see the method resolution order, and find all superclasses from there:
>>> bool.__mro__
(<class 'bool'>, <class 'int'>, <class 'object'>)
Upvotes: 12
Reputation: 330
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;
Upvotes: 0
Reputation: 18386
If you only want to check for int
:
if type(some_var) is int:
return True
else:
return False
Upvotes: 5
Reputation: 280291
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.
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.
Upvotes: 146
Reputation: 1021
Yes, this is right, it's a subclass of int, you can verify it using the interpreter:
>>> int.__subclasses__()
[<type 'bool'>]
Upvotes: 8