In Python 3.x
all classes are new-style classes; when defining a new class python implicitly makes it inherit from object
. As such, specifying object
in a class
definition is a completely optional:
class X: pass
class Y(object): pass
Both of these classes now contain object
in their mro
(method resolution order):
>>> X.__mro__
(__main__.X, object)
>>> Y.__mro__
(__main__.Y, object)
In Python 2.x
classes are, by default, old-style classes; they do not implicitly inherit from object
. This causes the semantics of classes to differ depending on if we explicitly add object
as a base class
:
class X: pass
class Y(object): pass
In this case, if we try to print the __mro__
of Y
, similar output as that in the Python 3.x
case will appear:
>>> Y.__mro__
(<class '__main__.Y'>, <type 'object'>)
This happens because we explicitly made Y
inherit from object when defining it: class Y(object): pass
. For class X
which does not inherit from object the __mro__
attribute does not exist, trying to access it results in an AttributeError
.
In order to ensure compatibility between both versions of Python, classes can be defined with object
as a base class:
class mycls(object):
"""I am fully compatible with Python 2/3"""
Alternatively, if the __metaclass__
variable is set to type
at global scope, all subsequently defined classes in a given module are implicitly new-style without needing to explicitly inherit from object
:
__metaclass__ = type
class mycls:
"""I am also fully compatible with Python 2/3"""