3

when I call type(int), it returns type; when I call type(10), it returns int (and, why is this not the string 'int', but just int?).

type seems to be a class inherited from the universal base class object. So, if it's a class, why I can call type(int)? is the operator '()' reloaded into a class method like C++?

I am quite confused.

Barmar
  • 741,623
  • 53
  • 500
  • 612
Benjamin
  • 93
  • 11
  • 2
    A few comments, as I don't share the confusion: 1) I think returning the actual type, `int`, is reasonable (preferred even) behavior. Why do you expect it to return a string of the type? 2) any class can implement `def __call__(self, *args, **kwargs)` to implement parenthesis-calling syntax – anon01 Dec 22 '20 at 06:19
  • When I call `type(int)` it returns ``. – Barmar Dec 22 '20 at 06:21
  • 2
    You have already looked at the Python documentation regarding this, right? See: https://docs.python.org/3/library/functions.html#type – codewelldev Dec 22 '20 at 06:21
  • All my calls to `type()` return ``. How are you just getting `something`? – Barmar Dec 22 '20 at 06:24
  • @anon01, 1) the int is a name of a class, why can it be returned or even compared ? for example, type(int) == int ? I would suppose the result of the type() is a string to demonstrate that it's an int type to the user. 2) yes, that's my question. – Benjamin Dec 22 '20 at 06:24
  • @Barmar, I using python 3.8 in spyder. Maybe it's due to version difference? – Benjamin Dec 22 '20 at 06:26
  • 3
    If you're seeing plain `int` when you call `type(10)`, you're probably using IPython, which has its own custom display handling. Either way, it returns the `int` class (and definitely not a string `'int'`, which would not be a type), but the display handling is different in different environments. – user2357112 Dec 22 '20 at 06:26
  • A type is a category of things. In most cases, a thing is not the same as the category it's a member of -- the exception is the category of categories. – Barmar Dec 22 '20 at 06:26
  • E.g. if you have a pet dog, you wouldn't say that it's equal to the category of all dogs. The name of your dog is Rover, the name of the category is Dogs. – Barmar Dec 22 '20 at 06:28
  • Classes in Python's object model are objects, too. So you can not just call `type('abc')` or `type(123)`, but you can also call `type(int)` or `type(type(int))` or `type(type(type(type(42))))`. – Ulrich Eckhardt Dec 22 '20 at 06:29
  • @anon01, And, __call__() is a method of an instance, it seems not a function of class – Benjamin Dec 22 '20 at 06:30
  • correct, it is an instance method. My point was that it makes objects callable like a function – anon01 Dec 22 '20 at 06:32
  • @UlrichEckhardt so when type(123) returns an int, or I just type an int in IPython, is it an instance, a string, or a name of class? – Benjamin Dec 22 '20 at 06:36
  • Sorry, I fail to parse that question. – Ulrich Eckhardt Dec 22 '20 at 06:37
  • Looks like it should be name of a class. For example one can write a self-defined class: class A and generate an instance a = A(), then the comparison type(a) == A is true – Benjamin Dec 22 '20 at 06:48
  • 2
    "it should be name of a class" -- not sure what you mean here. Anyhow, not just `type(a) == A` is true, but `type(a) is A` is true as well. Further, you can do `x = type(a)` and then `x()`, which will give you another A instance. – Ulrich Eckhardt Dec 22 '20 at 06:53
  • 1
    This is fundamentally a question about metaclasses, and there's [an extremely highly rated question](https://stackoverflow.com/questions/100003/what-are-metaclasses-in-python) on this site about those. `type` is the base metaclass, just like `object` is the base class of the Python type system. – Blckknght Dec 22 '20 at 06:56
  • 'name' of class is like a pointer to the class definition block. using x = type(a) gives another name, pointer to the same block, that't why x() works. I suppose. – Benjamin Dec 22 '20 at 06:57
  • 1
    Don’t think of it in terms of C(++). Think about it in Python’s own terms. Classes are first class objects, so `type` can return that object and doesn’t need to use its name as a stand-in. – deceze Dec 22 '20 at 07:22

1 Answers1

1

To clarify, type is a metaclass, of which classes are instances. Just as an ordinary object is an instance of a class, any class in Python 3, is an instance of the type metaclass.

This means, that type of an object is its corresponding class, but type of a class is its metaclass which is a type object as well.

> type(type)
<class 'type'>

Interestingly, the type of type is type as well. More details here.

As per official documentation -

class type(name, bases, dict)

With one argument, return the type of an object. The return value is a
type object and generally the same object as returned by object.__class__.

So, type class when passed a single argument should return similar results as object.__class__


To test this and understand methods, classes, and metaclasses in python, let's define our own class.

class myclass():
    def __init__(self,s):
        self.m = s
        self.n = s*2
        self.o = s*3

Notice that the __init__() method (which is invoked during instantiation of the class) takes in the parameter which allows the class to be instantiated as an object. Therefore, instantiating a class looks almost exactly the same as calling a method.

obj = myclass('hello world ')

#Returning the self dict
obj.__dict__
{'m': 'hello world ',
 'n': 'hello world hello world ',
 'o': 'hello world hello world hello world '}

Now let's check the class of the object and the class of the class to which the object belongs (metaclass).

#Class of object obj
> obj.__class__
__main__.myclass

#Class of class of obj = Class of myclass
> obj.__class__.__class__
type

#Class of class of class of obj = Class of type
> obj.__class__.__class__.__class__
type
Akshay Sehgal
  • 18,741
  • 3
  • 21
  • 51