65

I'm new to Python... and coming from a mostly Java background, if that accounts for anything.

I'm trying to understand polymorphism in Python. Maybe the problem is that I'm expecting the concepts I already know to project into Python. But I put together the following test code:

class animal(object): "empty animal class" class dog(animal): "empty dog class" myDog = dog() print myDog.__class__ is animal print myDog.__class__ is dog 

From the polymorphism I'm used to (e.g. java's instanceof), I would expect both of these statements to print true, as an instance of dog is an animal and also is a dog. But my output is:

False True 

What am I missing?

5
  • 18
    Note that checking an object's type is the opposite of polymorphism. Polymorphism is operating on an object regardless of its type. Commented May 14, 2010 at 18:28
  • This question is premised on a misunderstanding: isinstance(myDog, animal) does what you're looking for, myDog.__class__ is animal is wrong. Also in Python we use MixedCase for class names but lower_case_with_underscores for object names. So your classes should be called Animal, Dog and your object my_dog, dog1 etc. Commented Dec 31, 2019 at 17:24
  • 3
    Really your question title should be "How to test if an object is an instance of specified class or its subclasses?" But inspecting an object's class is the opposite of polymorphism, which counts on methods to exist, be implemented, and do the appropriate thing (or raise appropriate exception), as @dash-tom-bang says. Commented Jan 1, 2020 at 10:17
  • @anjaneyulubatta505 the link is not working. Commented Apr 19, 2020 at 14:33
  • @Idonknow Try reading learnbatta.com/blog/python-polymorphism-62 Commented Apr 19, 2020 at 15:45

4 Answers 4

79

The is operator in Python checks that the two arguments refer to the same object in memory; it is not like the is operator in C#.

From the docs:

The operators is and is not test for object identity: x is y is true if and only if x and y are the same object. x is not y yields the inverse truth value.

What you're looking for in this case is isinstance.

Return true if the object argument is an instance of the classinfo argument, or of a (direct or indirect) subclass thereof.

>>> class animal(object): pass >>> class dog(animal): pass >>> myDog = dog() >>> isinstance(myDog, dog) True >>> isinstance(myDog, animal) True 

However, idiomatic Python dictates that you (almost) never do type-checking, but instead rely on duck-typing for polymorphic behavior. There's nothing wrong with using isinstance to understand inheritance, but it should generally be avoided in "production" code.

Sign up to request clarification or add additional context in comments.

1 Comment

For classes which inherit from object you can also look at the classname.__mro__ tuple, but really, that's useful more for educational purposes.
43

phimuemue and Mark have answered your question. But this is ALSO an example of polymorphism in Python, but it's not as explicit as your inheritance based example.

class wolf(object): def bark(self): print "hooooowll" class dog(object): def bark(self): print "woof" def barkforme(dogtype): dogtype.bark() my_dog = dog() my_wolf = wolf() barkforme(my_dog) barkforme(my_wolf) 

1 Comment

Otherwise known as <strike>duck</strike> dog typing.
11

Try isinstance(myDog, dog) resp. isinstance(myDog, animal).

Comments

0

just nice example how it is possible to use same field of 2 totally different classes. It is more close to template.

class A: def __init__(self, arg = "3"): self.f = arg a = A() a.f # prints 3 class B: def __init__(self, arg = "5"): self.f = arg b = B() b.f # prints 5 def modify_if_different(s,t, field): if s.__dict__[field] != t.__dict__[field]: t.__dict__[field] = s.__dict__[field] else: s.__dict__[field] = None modify_if_different(a,b,"f") b.f # prints 3 a.f # prints 3 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.