3

I just read an article by Luca Cardelli and he explained types of polymorphism which are:

The article is named On Understanding Types, Data Abstraction, and Polymorphism.

Types of Polymorphism

Cardelli defines several types of polymorphism in this article:

  • Universal
    • parametric
    • inclusion
  • Ad-hoc
    • oveloading
    • coercion

I also found some theories says there are only two types of polymorphism broadly:

  • Run time Polymorphism
  • Compile time Polymorphism

So I am little bit confused. I am learning OOP in python and as I read python is dynamic type language so I request python experts please explain which types of polymorphism are used in Python?

  • 1
    This is a bit broad. Polymorphism is as polymorphism does. Can you be more specific about what you're confused about? – Robert Harvey Nov 9 '16 at 14:48
  • @RobertHarvey i am am new in python so i am confuse how many types of polymorphism python uses? – Pythonist Nov 9 '16 at 14:49
  • 1
    The short answer is that Python is dynamically typed so none of these ideas apply to Python. These notions really only make sense for statically typed languages. – gardenhead Nov 9 '16 at 15:16
  • 2
    @gardenhead: Even run-time polymorphism? – Robert Harvey Nov 9 '16 at 15:23
  • Are you interested in this from an academic perspective or are you interested in a more practical perspective? – JimmyJames Nov 9 '16 at 17:45
5

As you have found, there are many different definitions of polymorphism. This answer will address it from a practical perspective and may not align with academic definitions.

Sub-type polymorphism (via. inheritance)

This is the kind of polymorphism I believe most people think of with regard to the term polymorphism. This is where methods are inherited by sub-classes and then can be overridden. For example (Python 2.7):

class Foo(object):
  def test(self):
    print self.name()

  def name(self):
    return "Foo"

class Bar(Foo):
  def name(self):
    return "Bar"

foo = Foo()
bar = Bar()

print type(foo)
print type(bar)

print isinstance(bar, type(foo))

Foo().test()
Bar().test()

Output:

<class '__main__.Foo'>
<class '__main__.Bar'>
True
Foo
Bar

This works just sub-type polymorphism would in Java or C#.

Duck Typing

Python also has a feature called duck-typing. Technically this is also sub-type inheritance if you distinguish sub-types and inheritance (which I think is the right way to think about Python) The term comes from the idiomatic saying: "if it looks like a duck and quacks like a duck, it's probably a duck" which is often shortened to "if it quacks like a duck..." I would argue that whether or not this is polymorphism in the academic literature doesn't really matter because it can be used to solve the same problems:

class Foo(object):
  def test(self):
    print "Foo"

class Bar(object):
  def test(self):
    print "Bar"

foo = Foo()
bar = Bar()

print type(foo)
print type(bar)

print isinstance(bar, type(foo))

Foo().test()
Bar().test()

Output:

<class '__main__.Foo'>
<class '__main__.Bar'>
False
Foo
Bar

As you see we can get the same kind of behavior as before but now Bar is not a Foo. Duck-typing is very commonly used in Python programs where sub-typing is not. For example, it's common to create list-like objects where all (really: most) of the operations of a list are implemented and it is passed into methods as if it is as list even though from a pure typing perspective, it is not actually a type derived from list.

Parametric Polymorphism

I take this to mean stuff like generics in Java or C#. I don't think this is relevant to Python but I'm not up to speed on Python 3.

Method overloading

This an interesting case. From a pure Python perspective, this isn't meaningful because you can't overload methods. That is, you can't define the same method name twice at all. What's interesting is that in Jython (python that compiles to run on the JVM) you get a feature that neither Java nor Python have: double-dispatch. When determining what version of an overloaded Java method to call from a python statement, the runtime will look at the actual types of the parameters of the call and select the version dynamically. In Java overloaded methods are bound to calls at compile time instead which is technically polymorphic but in a really uninteresting way. Double-dispatch overloading can actually be used to implement some interesting effects. I expect that this would work similarly in IronPython and calls out to C# libraries.

I think I've covered most of the bases here. Comments are welcome for additional features that might be considered polymorphic. One thing that I'm not sure about is the ability to create synthetic or virtual properties/methods using __getattr__ or __setattr__ et al. Also, I think you could make the argument that passing method references around is type of polymorphism but maybe that's stretching things a bit too far.

  • Yeah, I still disagree on subtype polymorphism. Don't confuse inheritance with subtyping; inheritance is a (bad) way to implement programs, subtyping is a way to extend the set of well-typed programs. Python surely has inheritance, and the isinstance built-in checks for inheritance, not subytping. I mean, taking a step back, these concepts are really only typically defined for statically-typed languages, but even if we extend the definition in some natural way to dynamically-typed languages, Python still doesn't fit the bill. – gardenhead Nov 9 '16 at 18:53
  • @gardenhead I'm not really sure I understand your point. While you can make the argument that not all subtypes are subject to inheritance, all subclasses are subtypes of their parent classes in Python as in most OO languages. See this page on type objects. The word "inherited by subtypes" appears 36 times. I'm not sure how to square this with what you are saying. – JimmyJames Nov 9 '16 at 19:10
  • To be honest, I don't have enough understanding the the Python interpreter to be able to make sense of that post. But that's implementation anyway, so it shouldn't be relevant. I'll provide an example of what I mean. Let's say I have three classes: class A: foo = 1, class B(A), class C: foo = 2. So B inherits from A while C does not, but all three define member foo. If I have a function def do(a): a.foo. then I can pass an object of any of the three classes to do; it is allowed because of duck-typing. The fact that B inherits from A is irrelevant. – gardenhead Nov 9 '16 at 19:23
  • @gardenhead My link to the paper "Inheritance is subtyping" might have come off the wrong way, I linked to if because it contains the text "and reached a profoundly different conclusion: inheritance is not subtyping." Here's another reference that comes at it more from where you are sitting. I think makes the point that subclasses are inherently subtypes: "That's because duck typing, not subclassing, is the normal way to represent subtyping; inheritance is only one of three equally valid ways to implement subclassing;" – JimmyJames Nov 9 '16 at 19:24
  • @gardenhead So I can buy that duck-typing is the primary form of subtyping in Python. I'll even agree it's preferable. But I don't see how you get from there to (what I think you are saying): Python doesn't have types or that subclasses are not subtypes. You said in your post that "subtype polymorphism are meaningless in the context of duck-typing" but it would seem now that your argument is that duck-typing is subtype inheritance if we agree that duck-typing is subtyping. – JimmyJames Nov 9 '16 at 19:34
1

I haven't read the article, but I'll give this a shot.

Python is a dynamically-typed language. When academics talk about types, they are talking about statically-typed languages, unless stated otherwise. Dynamic and static typing share many of the same goals, but the methods of achieving these goals is vastly different - as such, what applies to one does not necessarily apply to the other.

This is the case here. Python specifically uses duck-typing, which means that any operation that can be performed, will be performed.

To elaborate, this means that the expression a.foo will succeed if object a has a foo method, regardless of what a actually is. Parametric and subtype polymorphism are meaningless in the context of duck-typing.

Python supports some typical coercion operators. I don't know the full list of them, but for example the expression 5 + 1.2 is valid, as the integer 5 will be coerced into the floating-point number 5.0.

Ad-hoc polymorphism through function overloading is not possible in Python.

I also found some theories says there are only two types of polymorphism broadly

This isn't a classification of polymorphism. It's just dynamic and static typing by a different name; dynamic typing uses run-time polymorphism (if any), and static typing uses compile-time polymorphism.

  • that's really healpful my doubt is clear , one more request can you please explain in brief in answer what is "duck-typing" it would be very helpful. – Pythonist Nov 9 '16 at 17:23
  • Python has types and sub-type polymorphism. What would lead you to think it doesn't? – JimmyJames Nov 9 '16 at 17:41
  • @JimmyJames Not in the usual sense. Any form of "sub-typing" in a dynamically-typed language is subsumed by duck-typing. – gardenhead Nov 9 '16 at 17:52
  • I'll add an answer with an example of sub-type polymorphism in Python – JimmyJames Nov 9 '16 at 17:53
  • @JimmyJames OK, I'm curious to see what you come up with. – gardenhead Nov 9 '16 at 18:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.