First of all, True
is not 1
:
>>> True is not 1
True
Second, as the documentation says
dir([object])
[...] With an argument, attempt to return a list of valid attributes for that object.
If the object has a method named __dir__()
, this method will be called and must return the list of attributes. This allows objects that implement a custom __getattr__()
or __getattribute__()
function to customize the way dir()
reports their attributes.
If the object does not provide __dir__()
, the function tries its best to gather information from the object’s __dict__
attribute, if defined, and from its type object. The resulting list is not necessarily complete, and may be inaccurate when the object has a custom __getattr__()
.
The resulting list is sorted alphabetically. [...]
Now, int
and bool
both have the __dir__
slot filled from object.__dir__
:
>>> int.__dir__
<method '__dir__' of 'object' objects>
>>> bool.__dir__
<method '__dir__' of 'object' objects>
And the documentation for object.__dir__
adds this one extra bit of information:
object.__dir__(self)
Called when dir()
is called on the object. A sequence must be returned. dir()
converts the returned sequence to a list and sorts it.
As the documentation says, dir
constructs a new list for each invocation and then sorts it. (We could also look into the code for _dir_object
which calls PySequence_List
on the return value of __dir__
; PySequence_List
takes a sequence as an argument, and returns a new list with the same elements as the original sequence; this newly created list is then sorted and returned)
>>> a = 1
>>> dir(a) is dir(a)
False
Third, True
is an instance of type bool
, which is a subclass of int
.
>>> isinstance(True, bool)
True
>>> isinstance(1, int)
True
>>> issubclass(bool, int)
True
>>> isinstance(True, int)
True
Additionally, bool
does not add any methods that are not already present in int
. And because the resulting list is sorted alphabetically,
>>> dir(1) == dir(True)
True