Why is bool a subclass of int?
From a comment on http://www.peterbe.com/plog/bool-is-int
It is perfectly logical, if you were around when the bool type was
added to python (sometime around 2.2 or 2.3).Prior to introduction of an actual bool type, 0 and 1 were the
official representation for truth value, similar to C89. To avoid
unnecessarily breaking non-ideal but working code, the new bool type
needed to work just like 0 and 1. This goes beyond merely truth value,
but all integral operations. No one would recommend using a boolean
result in a numeric context, nor would most people recommend testing
equality to determine truth value, no one wanted to find out the hard
way just how much existing code is that way. Thus the decision to make
True and False masquerade as 1 and 0, respectively. This is merely a
historical artifact of the linguistic evolution.
Credit goes to dman13 for this nice explanation.
Why is my boolean value an instance of int?
That's because bool
is a subclass of int
.
Quoting from the Python Data Model:
Booleans (bool)
These represent the truth values False and True. The two objects representing the valuesFalse
andTrue
are the only Boolean objects. The Boolean type is a subtype of the integer type, and Boolean values behave like the values 0 and 1, respectively, in almost all contexts, the exception being that when converted to a string, the strings"False"
or"True"
are returned, respectively.
Answer to comment:
Would it also return
True
if you didisinstance(bool, int)
?
No. True
and False
are instances of bool
and therefore instances of the parent class int
, but bool
itself is not an instance of int
. Being a class it's an instance of type
and a subclass of int
.
>>> isinstance(bool, int)
False
>>> isinstance(bool, type)
True
>>> issubclass(bool, int)
True
Why are booleans considered integers?
It is in the documentation: Numeric Types
There are three distinct numeric types: integers, floating point numbers, and complex numbers. In addition, Booleans are a subtype of integers.
True
and False
are numerically equal to 1
and 0
in Python, respectively.
Because bool is a subclass of int, as established above, isinstance
returns true, as documented:
isinstance(object, classinfo)
Return
True
if the object argument is an instance of the classinfo argument, or of a subclass thereof.
Why does bool exist when we can use int?
Why does bool exist when we can use int?
Well, you don't need something as large as an int
to represent two states so it makes sense to allow for a smaller type to save space
Why not we use an integer that can return only two possible values, Such as 1 or 0.
That is exactly what bool
is. It is an unsigned integer type that represents true (1) or false (0).
Another nice thing about having a specific type for this is that it express intent without any need for documentation. If we had a function like (warning, very contrived example)
void output(T const & val, bool log)
It is easy to see that log is an option and if we pass false it wont log. If it were instead
void output(T const & val, int log)
Then we aren't sure what it does. Is it asking for a log level? A flag on whether to log or not? Something else?
Comparing boolean and int using isinstance
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 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 handlingIf you want to detect objects whose specific class is exactly
float
orint
, 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.
Why bool and int are not considered as a type error when str and float is required?
bool
is a subclass of int
, which means they are both natural numbers. Natural numbers are a subset of real numbers, so they are acceptable where a float is acceptable.
That int
is acceptable where float
is specified is explicitly called out in PEP 484 -- Type Hints:
Rather than requiring that users write
import numbers
and then usenumbers.Float
etc., this PEP proposes a straightforward shortcut that is almost as effective: when an argument is annotated as having typefloat
, an argument of typeint
is acceptable[.]
The
str
component in yourUnion[]
doesn't play any role here; you could remove it and still the assignment would be accepted. It's purely thefloat
type annotation that makes12
andFalse
acceptable values.The
int()
call is entirely redundant, the12
literal syntax already produces anint
object.
python numbers.Number with boolean
Early Python (before 2.2?) didn't have a separate boolean type: people used 0 and 1 instead. When the bool type was added, it was made a subclass of ints to simplify the use of existing code in new Pythons.
Related Topics
How Does Functools Partial Do What It Does
Pandas Groupby, Then Sort Within Groups
How to Set Max_Retries for Requests.Request
Why Is Python Setup.Py Saying Invalid Command 'Bdist_Wheel' on Travis Ci
How to Build Multiple Submit Buttons Django Form
What Does the Percentage Sign Mean in Python
Python Class Instance Variables and Class Variables
How to Connect to MySQL in Python 3 on Windows
Iterating Through Directories with Python
In Python, Differencebetween ".Append()" and "+= []"
How to Switch Position of Two Items in a Python List
Read File Data Without Saving It in Flask
When to Use "While" or "For" in Python
Read Excel Cell Value and Not the Formula Computing It -Openpyxl
Why Is My Pygame Display Not Responding While Waiting for Input
Tensorflow Only Running on 1/32 of the Training Data Provided
Pandas Dataframe: Replace All Values in a Column, Based on Condition