I've little bit test to fully understand metaclass in python.
class Test(object):
pass
print Test.__class__
print Test.__class__.__class__
print Test.__class__.__class__.__class__
All of result is same type. but each of their address is not same
I can't really understand why metaclass has a metaclass recursively.
Explain me please?
Actually, addresses are the same:
>>> id(Test.__class__)
6384576
>>> id(Test.__class__.__class__)
6384576
>>> id(Test.__class__.__class__.__class__)
6384576
Everything is an object in Python, and each object must have a class (it should belong to some type). You can access that class/type reference by __class__ attribute, e.g.:
>>> (1).__class__
<type 'int'>
Everything includes classes itself, which are of class/type called type:
>>> (1).__class__.__class__
<type 'type'>
In the same time type 'type'> is also an object and should reference to some class/type. But since this is kind of special object, its __class__ attribute refers to itself:
>>> (1).__class__.__class__.__class__ is (1).__class__.__class__
True
When you do Test.__class__, you get back the type of Test, which is type (because Test is a class identifier).
type itself is again a class identifier, so you can call __class__ (which is inherited from object) on it and you get back that its type is, again, type because it is a class identifier.
Because you will always get back type which is a class itself, you can do this infinitely many times and will always get back that the current object's type is type.
All classes are classes which means they are derived from a class called class...
All the python's class object is build by the built-in function type(). You could also try this.
>>> T.__class__ == type
True
>>> type(type)
<type 'type'>
The T.class is equal to the build-in function type which is also an object implemented the call function. It's a attribute will be interpret as class(T). As your T class have no base class so type() is used which will return the type object.
You could check the python doc about customizing class creation to get detail about class creation.
To determining the appropriate metaclass
if no bases and no explicit metaclass are given, then type() is used
if an explicit metaclass is given and it is not an instance of type(), then it is used directly as the metaclass
if an instance of type() is given as the explicit metaclass, or bases are defined, then the most derived metaclass is used
Related
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'>)
>>> type(type)
<type 'type'>
I expect the type of type to be a function since it's used to return the type of the argument. Does this mean a type can accept arguments? Is type something unusual/special?
type is a metaclass: a class whose instances are also classes. The type of any other builtin class will also be type - eg:
>>> type(object)
<class 'type'>
>>> type(list)
<class 'type'>
Indeed, every (new-style) class will also be an instance of type, although if it is defined with a custom metaclass, type(my_class) will be that metaclass. But since every metaclass is required to inherit from type, you will have, for any class:
>>> isinstance(my_class, type)
True
Classes are objects. All objects are instances of a class. So since a class is an object, it is an instance of some class. The class that a class is an instance of is named type. It is the base metaclass.
Originally type() was just a function that returned an object's class. In Python 2.2, user-defined classes and built-in types were unified, and type became a class. For backward compatibility, it still behaves like the old type() function when called with one argument.
type is Python's class ur-type. When called with a single argument it returns the type of the argument. When called with 3 arguments it returns a class whose characteristics are determined by the arguments.
As can be clearly seen in the documentations -
class type(object)
class type(name, bases, dict)
With one argument, return the type of an object. The return value is a type object. The isinstance() built-in function is recommended for testing the type of an object.
type is a class, not a function.
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.
Here's a piece of code that I cannot understand:
class COWMeta(type):
pass
class COWDictMeta(COWMeta):
....
I know how to create a new class in python:
class MyClass(BaseClass):
...
But as the manual states, 'type' is function.
type(...)
Function of __builtin__ module
type(object) -> the object’s type type(name, bases, dict) -> a new type
How can a class inherit from a function? And what does that piece of code mean?
type is the basic object type in python. Like many object types in python, it acts as a constructor for creating new types, but in it's simplest form it'll return the type of existing objects. It then looks like a function. Compare this to int() and list(), for example.
In python, you can create new types, also called metaclasses, allowing you to do all sorts of powerful and interesting tricks in Python. Basing a class definition on type means you are creating a new metaclass.
See What is a metaclass in Python? for an in-depth answer on what metaclasses are.
type is not a function in the same way that, eg:
def foo():
pass
is a function. It is callable like a function (and like many other objects in Python), but it is actually coded as a class. type itself can show you this difference:
>>> type(type)
<class 'type'>
>>> type(foo)
<class 'function'>
The docs call it a 'function' not because of how it is implemented, but because of how it is commonly used. This is broadly similar to, for example, itertools.permutations, which while not explicitly called a function by the docs is implied to be one:
Return successive r length permutations of elements in the iterable.
But itertools.permutations is implemented as a class:
>>> type(itertools.permutations)
<class 'type'>