📅 2017-Dec-11 ⬩ ✍️ Ashwin Nanjappa ⬩ 🏷️ python, type ⬩ 📚 Archive
Given any type in Python, you can easily discover its ancestor and descendant types. This ease of discovery of the internals of the language is one of my favorite features of Python.
Remember that all types are descended from the object
type.
Even type
is a type and it is a child of the object
type.
The __base__
attribute of any type has a string value with the name of the parent type.
The __subclasses__
method of any type lists the child types.
To determine which are the standard types (or builtin types or builtins as they are called in Python), check the __module__
attribute of the type. If it is builtins
in Python 3 or __builtin__
in Python 2, then that is a standard type.
If you start from object
, you can actually list the entire type hierarchy tree. A script that does just that can be found here:
#!/usr/bin/env python3
"""Print hierarchy of types present in Python."""
import argparse
import sys
def is_builtin(t):
"""Check if type is builtin."""
= "__builtin__" if sys.version_info.major <= 2 else "builtins"
builtin_s return t.__module__ == builtin_s
def process_a_type(t, level, options):
# Not a builtin type
if options.only_builtins and not is_builtin(t):
return
# Print type
= ""
s if level > 0:
+= " " * (level - 1)
s += "+-- "
s += t.__name__
s if options.show_module:
+= " ({})".format(t.__module__)
s print(s)
# -type- has no subclasses
if t.__name__ == "type":
return
# Recurse through child types
for st in t.__subclasses__():
process_a_type(
st,+ 1,
level
options,
)
def get_args():
= argparse.ArgumentParser(description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter)
ap "--only_builtins", default=False, action="store_true", help="Only show builtin types")
ap.add_argument("--show_module", default=False, action="store_true", help="Show module name beside type")
ap.add_argument("--import_module", default="", type=str, help="Import this module to get its types")
ap.add_argument(= ap.parse_args()
args return args
def main():
= get_args()
args
# Import module wanted by user
if args.import_module:
__import__(args.import_module)
# -object- type is root
process_a_type(object,
0,
args,
)
if __name__ == "__main__":
main()
object
+-- type
+-- dict_values
+-- odict_values
+-- tuple_iterator
+-- set
+-- fieldnameiterator
+-- frame
+-- dict_keyiterator
+-- PyCapsule
+-- coroutine
+-- bytearray
+-- NoneType
+-- list
+-- dict
+-- getset_descriptor
+-- method-wrapper
+-- method
+-- str_iterator
+-- formatteriterator
+-- str
+-- set_iterator
+-- range_iterator
+-- memoryview
+-- cell
+-- generator
+-- map
+-- list_iterator
+-- stderrprinter
+-- reversed
+-- method_descriptor
+-- code
+-- weakproxy
+-- int
+-- bool
+-- ellipsis
+-- module
+-- dict_items
+-- odict_items
+-- bytearray_iterator
+-- Struct
+-- moduledef
+-- filter
+-- staticmethod
+-- tuple
+-- frozenset
+-- managedbuffer
+-- coroutine_wrapper
+-- function
+-- builtin_function_or_method
+-- odict_iterator
+-- float
+-- range
+-- super
+-- dict_keys
+-- odict_keys
+-- list_reverseiterator
+-- bytes_iterator
+-- member_descriptor
+-- wrapper_descriptor
+-- property
+-- instancemethod
+-- zip
+-- weakref
+-- slice
+-- longrange_iterator
+-- dict_valueiterator
+-- EncodingMap
+-- callable_iterator
+-- mappingproxy
+-- BaseException
+-- Exception
+-- TypeError
+-- StopAsyncIteration
+-- SyntaxError
+-- IndentationError
+-- TabError
+-- AttributeError
+-- AssertionError
+-- StopIteration
+-- MemoryError
+-- BufferError
+-- NameError
+-- UnboundLocalError
+-- LookupError
+-- IndexError
+-- KeyError
+-- EOFError
+-- ImportError
+-- ValueError
+-- UnicodeError
+-- UnicodeEncodeError
+-- UnicodeDecodeError
+-- UnicodeTranslateError
+-- RuntimeError
+-- RecursionError
+-- NotImplementedError
+-- SystemError
+-- Warning
+-- UserWarning
+-- DeprecationWarning
+-- BytesWarning
+-- SyntaxWarning
+-- PendingDeprecationWarning
+-- FutureWarning
+-- ResourceWarning
+-- ImportWarning
+-- RuntimeWarning
+-- UnicodeWarning
+-- ReferenceError
+-- OSError
+-- ConnectionError
+-- BrokenPipeError
+-- ConnectionAbortedError
+-- ConnectionRefusedError
+-- ConnectionResetError
+-- BlockingIOError
+-- NotADirectoryError
+-- PermissionError
+-- FileExistsError
+-- TimeoutError
+-- IsADirectoryError
+-- InterruptedError
+-- ProcessLookupError
+-- FileNotFoundError
+-- ChildProcessError
+-- ArithmeticError
+-- FloatingPointError
+-- OverflowError
+-- ZeroDivisionError
+-- GeneratorExit
+-- KeyboardInterrupt
+-- SystemExit
+-- dict_itemiterator
+-- classmethod
+-- NotImplementedType
+-- iterator
+-- bytes
+-- enumerate
+-- classmethod_descriptor
+-- complex
+-- traceback
+-- weakcallableproxy
Note how bool
is a child type of the int
type.
In Python 2.7.12, I found that there are 60 builtin types in the tree:
object
+-- type
+-- weakref
+-- weakcallableproxy
+-- weakproxy
+-- int
+-- bool
+-- basestring
+-- str
+-- unicode
+-- bytearray
+-- list
+-- NoneType
+-- NotImplementedType
+-- traceback
+-- super
+-- xrange
+-- dict
+-- set
+-- slice
+-- staticmethod
+-- complex
+-- float
+-- buffer
+-- long
+-- frozenset
+-- property
+-- memoryview
+-- tuple
+-- enumerate
+-- reversed
+-- code
+-- frame
+-- builtin_function_or_method
+-- instancemethod
+-- function
+-- classobj
+-- dictproxy
+-- generator
+-- getset_descriptor
+-- wrapper_descriptor
+-- instance
+-- ellipsis
+-- member_descriptor
+-- file
+-- PyCapsule
+-- cell
+-- callable-iterator
+-- iterator
+-- EncodingMap
+-- fieldnameiterator
+-- formatteriterator
+-- module
+-- classmethod
+-- dict_keys
+-- dict_items
+-- dict_values
+-- deque_iterator
+-- deque_reverse_iterator
+-- Struct
Note how str
and unicode
are child types of the basestring
type. Also observe how this differs from Python 3 builtin types.
Also notice how in Python 2 the exception types are not builtin types.