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
Trueto stop being anint, 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
floatorint, 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