Search code examples
pythonnew-style-class

Difference between type(obj) and obj.__class__


What is the difference between type(obj) and obj.__class__? Is there ever a possibility of type(obj) is not obj.__class__?

I want to write a function that works generically on the supplied objects, using a default value of 1 in the same type as another parameter. Which variation, #1 or #2 below, is going to do the right thing?

def f(a, b=None):
  if b is None:
    b = type(a)(1) # #1
    b = a.__class__(1) # #2

Solution

  • type(obj) and type.__class__ do not behave the same for old style classes in Python 2:

    >>> class a(object):
    ...     pass
    ... 
    >>> class b(a):
    ...     pass
    ... 
    >>> class c:
    ...     pass
    ... 
    >>> ai = a()
    >>> bi = b()
    >>> ci = c()
    >>> type(ai) is ai.__class__
    True
    >>> type(bi) is bi.__class__
    True
    >>> type(ci) is ci.__class__
    False
    >>> type(ci)
    <type 'instance'>
    >>> ci.__class__
    <class __main__.c at 0x7f437cee8600>
    

    This is explained in the documentation:

    For an old-style class, the statement x.__class__ provides the class of x, but type(x) is always <type 'instance'>. This reflects the fact that all old-style instances, independent of their class, are implemented with a single built-in type, called instance.