I thought that I realized this relationship: In Python everything is an object, and every object has a type. But what about classes? A class is a blueprint of an object, and an object is instance of a class. But I have read in an article that in Python, classes are themselves objects. I thought that an object cannot exist without its blueprint - its class. But, if class is an object, how it can exist?
>>> type.__bases__
(<class 'object'>,)
>>> int.__bases__
(<class 'object'>,)
>>> str.__bases__
(<class 'object'>,)
So, the class object is the blueprint of every object?
>>> type(str)
<class 'type'>
>>> type(int)
<class 'type'>
>>> type(type)
<class 'type'>
So, class type is blueprint of every other type?
But type is an object itself. I cannot understand this. I cannot imagine that classes are objects.
Everything that can be given a name in Python is an object - including functions, classes and metaclasses. Every object has an associated type or class (these are two names for the same thing -- "type" and "class" are the same in Python 3). The type itself is an object again, and has itself an associated type. The type of a type is called a metaclass (of course, it could equally well be called a metatype, but the latter word is not used). You can use type() to determine the type of an object. If you iteratively query the type of an object, the type of its type and so on, you will always end up with the type type at some point, usually after two steps:
type(3) # --> int
type(int) # --> type
type(type) # --> type
Another example, using "meta-metaclasses":
class A(type):
pass
class B(type, metaclass=A):
pass
class C(metaclass=B):
pass
c = C()
type(c) # --> C
type(C) # --> B
type(B) # --> A
type(A) # --> type
type(type) # --> type
There is no contradiction in type being itself of type type.
Related
I declare a variable and assign it an integer value, its type is <class 'int>. Shouldn't that be an object?
If I define a class and instantiate its object, the type of the object is again class.
If I assign a variable to object, the variable is <class 'object> and its type is <class 'type'>
(refer the corresponding shell entries)
To be precise, I want to understand what it means when (in tutorials) it is said that everything in Python is an object, when I can see the that type always says it's a class?
Can anyone please explain this discrepancy?
In Python shell:
1.
>>> a = 1
>>> type(a)
>>> <class 'int'>
>>> class Something:
... pass
...
>
>>> s = Something()
>>> type(s)
>>> <class '__main__.Something'>
>>> t = object
>>> t
>>> <class 'object'>
>
>>> type(t)
>>> <class 'type'>
All values in Python are objects, in the sense that each value has a type associated with it. (Variables themselves to not have types; type(a) simply reports the inherent type of whatever value as assigned to the name a.)
Further, classes themselves are first-class values with their own type. Just as the type of 3 is int, the type of int is type. Even type is a value, with the somewhat surprising feature that the type of type is type.
object is the root of the class hierarchy, so all classes have object as an ancestor. (Just as type has type type, object is the parent of object, which is probably less surprising if you are used to any class being a trivial subclass of itself.) All classes, including object, are instances of type type.
With the definition (not declaration) a = 1, you assign the value 1 (with type int) to the name a.
With s = Something(), you create a value of type Something and assign it to the name s.
With t = object, you assign the value object (with the type type) to the name t.
Hmm..., this is not only a vocabulary question. In Python 3 the object class is a special class whose any other class (including int) derives. Everything is an object could more verbosely be said everything is an instance of a class that is a subclass of object.
The last one says that most classes including object are direct instances of another very special class which it type. In fact in Python all classes are instances of their metaclass, and except for special requirement the standard metaclass is type and metaclasses are expected to be subclasses of type
If we want to go one step further, we realize that as type being a class, is a subclass of object: type.__mro__ gives (<class 'type'>, <class 'object'>). On a strict logical and mathematical point of view, it can be seen as rather weird (the set of all sets cannot exists in set theory). But as the basic types and functions of Python are built-in they are not required to be defined in Python language and we do not fall in a definition loop.
I'm currently learning python OOP model and have been told
type itself derives from object, and object derives from type
I understand that object is the default superclass of every class in python 3.x, and type class is used to created classes (i.e. class object). object and type together (somehow) forms the bases of python OOP, but I am still confused as ever about the statement above.
Could someone provide a detailed explanation on the relationship between object and type, and the roles they play in python OOP. Thanks
We need to distinguish subclassing from instantiation. The exact rules can vary with the language, but in Python 3.x--
All classes are subclasses of object (well, except for object itself). object is the root of the class hierarchy.
The type class is a subclass of object.
All objects are instances of a class.
Classes are themselves objects. (This is not true in every language.)
Class objects, being objects, are instances of a class--class objects are instances of the class type (the default metaclass).
Yes, type is a class and an object, and it is an instance of type. type has class type.
Yes, object is a class and an object, and it is an instance of type. object has class type.
You can see the class of an object by using .__class__ or type() on it.
You can see the superclasses of a class by using .__mro__ (method resolution order) on it.
>>> type(object)
<class 'type'>
>>> type(type)
<class 'type'>
>>> object.__mro__
(<class 'object'>,)
>>> type.__mro__
(<class 'type'>, <class 'object'>)
I'm trying to look under the hood in idle to wrap my head around python custom classes and how they are stored in memory. Suppose I have the following code:
class Point:
pass
x=Point()
print(x)
Given the following output:
<__main__.Point object at 0x000002A3A071DF60>
I know that since my class consists of no code, when I create an object of type Point, an object of type object is implicitly created from which the Point object x inherits such methods as __str__ etc. However, I cant seem to see the connection ie. when I type dir(x), I dont see any attribute that stores a reference to an object of type object. Am I misunderstanding how it works or is there some attribute that I am unaware of?
There is no (direct) instance of type object involved. When you call Point(), a Point instance is created, and nothing else. Inheritance is a mechanism that operates on classes, not on instances.
Python objects have two properties: Their type and their value. The type of x is Point. The value of x is represented by its __dict__, which is empty (because it has no attributes):
>>> type(x)
<class '__main__.Point'>
>>> x.__dict__
{}
There is no reference to an object instance, because no such instance exists. The inheritance from object manifests in the class Point:
>>> Point.__base__
<class 'object'>
>>> Point.mro()
[<class '__main__.Point'>, <class 'object'>]
So the reason why x can use object methods is because Point inherits from object, not because there's a hidden object instance stored in x. You can see that Point has access to all object methods:
>>> Point.__str__ is object.__str__
True
>>> Point.__init__ is object.__init__
True
# etc...
So, by proxy, x has access to all object methods as well.
you may be looking for Point.__mro__? the method resolution order of the class Point. it tells you in what order python will go looking for methods if you call x.method. in your case this will be:
print(Point.__mro__) # or Point.mro()
# (<class '__main__.Point'>, <class 'object'>)
I wonder about that it seems like that the method resolution order attribute mro is not available in Python 3.x anymore. Using Python 3.5.2 and creating a random class object instance A, built-in or self-implemented, for example
A = dict()
and then calling
A.__mro__
doesnt work, raising
AttributeError: 'A' object has no attribute '__mro__'
I tried to use A.mro(), but this gives the same type of exception.
How do I receive the method resolution order now?
That doesn't work on instances. The error hints that the variable A in question is not bound to a type, but to an instance of class A. types (classes) very much do have __mro__:
>>> int.__mro__
(<class 'int'>, <class 'object'>)
>>> class Foo():
... pass
...
>>> Foo.__mro__
(<class '__main__.Foo'>, <class 'object'>)
Since A is an instance of a type and not the type itself, you can use type(A).__mro__.
Additionally, your code wouldn't have worked in Python 2 either; no, instances didn't have __mro__ there either.
In python 3 everything is a object. I drew a diagram about relation of classes. Is this diagram correct?
the hard part is about type and object classes. how are they in relation ?
type is a object ? or object is a type ?
>>> x=type
>>> type(x)
<class 'type'>
>>> x=object
>>> type(x)
<class 'type'>
As far as I know, the class relations are kind of like this in Python 3:
Every class is a subclass of object
Every class is an instance of type
Every class is created by the type class or an other metaclass, which derives from type. Because of this every class is an instance of type (including type!) Every class will return True for isinstance(cls, type).
In Python 3, every class is also a subclass from object. Every class or instance will return True for isinstance(cls_or_instance, object)
A special case is metaclasses. A metaclass derives from type, so every metaclass will return True for issubclass(metaclass, type) and isinstance(metaclass, type)
The type object is itself an object. Note though that the inheritance model of python is not the same as in other OO-languges, much of it depends on duck typing rather than inheritance.
Note that type(x) returns the type of the object, that type(object) returns <class 'type'> means nothing more than the type of object (which is the type all objects has) is a type (the type all types are), type itself is a type so the type of it is again type.