1

How does the type function, when passed a single argument, determines the type of the object it is passed?

And is it possible to customize what it returns by making some particular changes in the object's class definition?

Edit:

I doubt it uses the object.__class__ attribute because in spite of overriding the __getattribute__ function of the class to return some arbitrary value when querying for __class__ it returns the actual type when the type checked through type.

>>> class Foo(object):
...     def __getattribute__(self, name):
...         if name == "__class__":
...             return type("Bar", (), {})
...         else:
...             return super(Foo, self).__getattribute__(name)
... 
>>> bar = Foo()
>>> bar.__class__ , type(bar)
(<class '__main__.Bar'>, <class '__main__.Foo'>)
Bleeding Fingers
  • 6,993
  • 7
  • 46
  • 74

4 Answers4

2

This is an implementation detail, but I would assume it does so by inspecting some data in the internal representation of the value.

After all, the Python system must be able to determine the type of each value in order to figure out how to do operations on them.

The documentation doesn't mention any way of modifying or affecting the value returned by the type() built-in function, so I don't think you can do that.

unwind
  • 391,730
  • 64
  • 469
  • 606
1

type will detail what's in the class attribute, this is a reference to the class of which the object is an instance of:

>>> num = 5
>>> num.__class__
<class 'int'>
>>> type(num)
<class 'int'>
>>> type(type(num))
<class 'type'> 

This has to do with metaclasses, a brilliant answer to what metaclasses are and how they work can be found here What is a metaclass in Python Alternativley, this is guide is very thorough Python types and Objects

Community
  • 1
  • 1
HennyH
  • 7,794
  • 2
  • 29
  • 39
0

Class instances have a special attribute called __class__.

In [1]: class A:
   ...:     pass
   ...: 

In [2]: class B:
   ...:     pass
   ...: 

In [3]: a = A()

In [4]: type(a), a.__class__
Out[4]: (__main__.A, __main__.A)

In [5]: a.__class__ = B

In [6]: type(a), a.__class__
Out[6]: (__main__.B, __main__.B)

In Python 2.x you need new-style classes to see this output. Otherwise:

In [4]: type(a), a.__class__
Out[4]: (instance, __main__.A)

In [5]: a.__class__ = B

In [6]: type(a), a.__class__
Out[6]: (instance, __main__.B)
Lev Levitsky
  • 63,701
  • 20
  • 147
  • 175
0

From the docs:

Each value is an object, and therefore has a class (also called its type). It is stored as object.__class__.

Kos
  • 70,399
  • 25
  • 169
  • 233