3

First, I'm sorry if I'm asking something dumb, because I'm new to Python...
I was reading http://docs.python.org/3.1/reference/datamodel.html#objects-values-and-types and saw that phrase:

The type() function returns an object’s type (which is an object itself)

Of course, I decided to check this:

>>> def someFunction(x):
...     return x * x
...     
>>> type(someFunction)
<class 'function'>
>>> type(type)
<class 'type'>

So, looks like functions have the function type, but then why type function has a different type if it is a function? Or the docs are lying and it's not really a function?

Display Name
  • 8,022
  • 3
  • 31
  • 66
  • 6
    It's a function implemented in C. And it is it's own type. Yes, it's turtles, all the way down! – Martijn Pieters Mar 22 '14 at 08:45
  • 1
    `isinstance(type,object)`, `isinstance(object,type)`, and `isinstance(type,type)` are all `True`. *Obviously*. :-) – roippi Mar 22 '14 at 08:59
  • 1
    Also see [this answer](http://stackoverflow.com/a/6581949/1599111). It's about metaclasses, but it should make it clear to you what the two distinct functions (type checking and class factory) of `type()` in Python are used for. – Lukas Graf Mar 22 '14 at 12:18

4 Answers4

10

Yes, type is a function, but it is implemented in C.

It also has to be it's own type, otherwise you could not do:

>>> def foo(): pass
... 
>>> type(foo)
<type 'function'>
>>> type(type)
<type 'type'>
>>> isinstance(type(foo), type)
True

e.g. you could not test if a type is a type, if type's type was not type but function. With me still?

Technically speaking, type is a callable, and has two related roles to play. It is a metaclass (a class factory) and the base for all types in Python, and when called it produces a type instance (<type 'function'> is an instance of the type type).

The same applies to all types (including classes); call them and they produce a new instance of the given type.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
2
  1. Note that in Python anything is object. An object may be callable, i.e. work as function.
  2. type is a built-in function, i.e. object of type that you can call as function. You can call it with one argument to get the type of an object. But there is also another use case.
  3. type is a metaclass, this means it is a type itself and can create classes (which are objects too).
  4. All classes (and also metaclasses) are callable, this is one more reason why type is function. You can call it with three arguments to create a class.
  5. type is basic built-in metaclass. So it is a base of anything in Python. Because type is on top of hierarchy of types, type(type) returns type, i.e. type is type of itself.

You also may wonder:

Community
  • 1
  • 1
raacer
  • 5,302
  • 3
  • 27
  • 46
0

type is a class, that deals with class objects. Invoking it with an object is only one way to use it. You can also use it to create meta classes.

For example

>>> MyMetaClass = type("MyMetaClass", (object,), {'foo': 'bar'})
>>> newmeta = MyMetaClass()
>>> newmeta.foo
'bar'
>>> type(MyMetaClass)
<type 'type'>
>>> type(newmeta)
<class '__main__.MyMetaClass'>
lvc
  • 34,233
  • 10
  • 73
  • 98
Victory
  • 5,811
  • 2
  • 26
  • 45
  • Your 'metaclass' isn't actually a metaclass - to be a metaclass, you would have to have `isinstance(newmeta, type)` be True. – lvc Mar 22 '14 at 09:08
  • 1
    Which means `MyMetaClass` is a class but not a metaclass. For it to be a metaclass, its *instances* would need to be classes, which they're not. It would also need to be a subclass of type, which it isn't. – lvc Mar 22 '14 at 09:16
  • @ivc - i see what you are saying now, you are right. +1 – Victory Mar 22 '14 at 09:19
0

You should understand some concepts first:

  1. Everything in Python is an object. Every object created in Python is inherited from parent class 'type', its called a Metaclass. Metaclass is parent class of all the object in Python world. So what is the type of 'type' metaclass since everything is an object in Python? its 'type' only. 'type' object is of self type.
  2. Now 'type()' is a function and 'type' is an object.

class XYZ: pass print(type(XYZ))

output: <class 'type'>