Reputation: 1582
I just noticed that
isinstance(myob, MyClass)
does not only return True
when myob
is an instance of MyClass
but also if myob
is an instance of a class that inherits from MyClass
.
To be more clear, consider the following:
class Book(object):
def __init__(self, cover)
self._cover = cover
class Novel(Book):
def __init__(self, cover, category):
Book.__init__(self, cover)
self._category = category
When instanciating Novel as follows:
novel = Novel('hardcover', 'police')
then
print(isinstance(novel, Book))
and
print (isinstance(novel , Novel))
both print True
.
Why is that so? In my sense, novel
is a Novel
instance, not a Book
one...
Also, relevant to this :
In order to get the "grand-mother" (sic) class, I do:
print(novel.__class__.__bases__)
Is there a more direct way?
Upvotes: 0
Views: 7143
Reputation: 78690
This transitive behavior is how it should work intuitively ...
>>> class Text:
...: pass
...:
...:
>>> class Book(Text):
...: pass
...:
...:
>>> class Novel(Book):
...: pass
...:
...:
>>> n = Novel()
>>> isinstance(n, Novel)
>>> True
>>> isinstance(n, Book)
>>> True
>>> isinstance(n, Text)
>>> True
... because a Novel
is-a Novel
, but also is-a Book
and is-a Text
.
If you want to know whether a class (or instance of a class) is a direct ancestor of another class, you can use the __subclasses__
method of class objects.
>>> Text.__subclasses__()
>>> [__main__.Book]
>>> Book.__subclasses__()
>>> [__main__.Novel]
>>> Novel.__subclasses__()
>>> []
>>>
>>> Novel in Text.__subclasses__()
>>> False
>>> type(n) in Text.__subclasses__()
>>> False
>>> Novel in Book.__subclasses__()
>>> True
>>> type(n) in Book.__subclasses__()
>>> True
edit: YourClass.__bases__
also gives you all direct parent classes.
>>> Novel.__bases__
>>> (__main__.Book,)
Upvotes: 6
Reputation: 77902
Inheritance is "is a" relationship - if Duck
inherit from Bird
then obviously a duck (instance of Duck
) is ALSO a bird
(instance of Bird
), so the behaviour you observe is really the expected one (and this holds for all class-based OOPLs).
If you want to check the exact type of an object, you can get it using type(obj)
- which will return the class of object - and do an identity test against the desired class, ie:
obj = 42
print(type(obj) is int)
Upvotes: 4