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.
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'>)
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
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.
How can I get the parent class(es) of a Python class?
Use the following attribute:
cls.__bases__
From the docs:
The tuple of base classes of a class
object.
Example:
>>> str.__bases__
(<type 'basestring'>,)
Another example:
>>> class A(object):
... pass
...
>>> class B(object):
... pass
...
>>> class C(A, B):
... pass
...
>>> C.__bases__
(<class '__main__.A'>, <class '__main__.B'>)
If you want all the ancestors rather than just the immediate ones, use cls.__mro__.
For versions of Python earlier than 3.5, use inspect.getmro:
import inspect
print inspect.getmro(cls)
Usefully, this gives you all ancestor classes in the "method resolution order" -- i.e. the order in which the ancestors will be checked when resolving a method (or, actually, any other attribute -- methods and other attributes live in the same namespace in Python, after all;-).
The fastest way to get all parents, and in order, is to just use the __mro__ built-in.
For instance, repr(YOUR_CLASS.__mro__).
The following:
import getpass
getpass.GetPassWarning.__mro__
...outputs, in order:
(<class 'getpass.GetPassWarning'>, <type 'exceptions.UserWarning'>, <type 'exceptions.Warning'>, <type 'exceptions.Exception'>, <type 'exceptions.BaseException'>, <type 'object'>)
There you have it. The "best" answer may have more votes but this is so much simpler than some convoluted for loop, looking into __bases__ one class at a time, not to mention when a class extends two or more parent classes. Importing and using inspect just clouds the scope unnecessarily.
New-style classes have an mro method you can call which returns a list of parent classes in method resolution order.
Use bases if you just want to get the parents, use __mro__ (as pointed out by #naught101) for getting the method resolution order (so to know in which order the init's were executed).
Bases (and first getting the class for an existing object):
>>> some_object = "some_text"
>>> some_object.__class__.__bases__
(object,)
For mro in recent Python versions:
>>> some_object = "some_text"
>>> some_object.__class__.__mro__
(str, object)
Obviously, when you already have a class definition, you can just call __mro__ on that directly:
>>> class A(): pass
>>> A.__mro__
(__main__.A, object)
If you want to ensure they all get called, use super at all levels.
If you have a variable and want to get its class and parent classes use type() method which will give class for a variable
val="happy coding"
print(type(val).__mro__)
Output:
(<class 'str'>, <class 'object'>)
This funciton will print the all the classes of an object, while in each step the next object will the left most parent.
def print_root_left(class_):
while True:
print(class_)
# Check there if are no bases then we have reached the root class
if not class_.__bases__:
break
class_=class_.__bases__[0] # use the left most parent
example = "hello"
print_root_left(example.__class__)