Quanti tipi di polimorfismo esistono nel linguaggio Python?

3

Ho appena letto un articolo di Luca Cardelli e ha spiegato i tipi di polimorfismo che sono:

L'articolo è denominato Informazioni sui tipi, sull'astrazione dei dati e sul polimorfismo .

Tipi di polimorfismo

Cardelli definisce diversi tipi di polimorfismo in questo articolo:

  • Universal
    • parametrico
    • inclusione
  • Ad-hoc
    • oveloading
    • coercizione

Ho anche scoperto che alcune teorie dicono che ci sono solo due tipi di polimorfismo in generale:

  • Polimorfismo a tempo di esecuzione
  • Polimorfismo del tempo di compilazione

Quindi sono un po 'confuso. Sto imparando OOP in Python e mentre leggo python è un linguaggio di tipo dinamico, quindi chiedo agli esperti Python di spiegare quali tipi di polimorfismo sono usati in Python?

    
posta Pythonist 09.11.2016 - 15:46
fonte

2 risposte

4

Come hai trovato, ci sono molte diverse definizioni di polimorfismo. Questa risposta sarà affrontata da una prospettiva pratica e potrebbe non essere in linea con le definizioni accademiche.

Polimorfismo del sottotipo (via. ereditarietà)

Questo è il tipo di polimorfismo che ritengo la maggior parte delle persone pensa riguardo al termine polimorfismo. Questo è dove i metodi sono ereditati dalle sottoclassi e quindi possono essere sovrascritti. Ad esempio (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

Funziona solo il polimorfismo del sottotipo in Java o C #.

Duck Typing

Python ha anche una funzionalità chiamata digitazione anatra. Tecnicamente questa è anche ereditarietà del sottotipo se si distinguono sottotipi ed ereditarietà (che penso sia il modo giusto per pensare a Python) Il termine deriva dal detto idiomatico: "se sembra un'anatra e ciarlatano come un'anatra, è probabilmente un'anatra "che viene spesso abbreviata in" se cova come un'anatra ... "Direi che questo non è il polimorfismo nella letteratura accademica, non importa perché può essere usato per risolvere gli stessi problemi :

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

Come vedi, possiamo ottenere lo stesso tipo di comportamento di prima, ma ora Bar non è un Foo. La tipizzazione delle anatre è molto comunemente usata nei programmi Python in cui la sub-tipizzazione non lo è. Ad esempio, è comune creare oggetti tipo elenco in cui vengono implementate tutte (veramente: la maggior parte) delle operazioni di list e vengono passate in metodi come se è come list pari sebbene da una prospettiva di digitazione pura, non è in realtà un tipo derivato dalla lista.

Polimorfismo parametrico

Prendo questo per dire cose come generici in Java o C #. Non penso che questo sia rilevante per Python, ma non sono veloce su Python 3.

Sovraccarico del metodo

Questo è un caso interessante. Da una prospettiva pura di Python, questo non ha senso perché non è possibile sovraccaricare i metodi. Cioè, non è possibile definire due volte lo stesso nome del metodo. La cosa interessante è che in Jython (python che compila per essere eseguito su JVM) si ottiene una funzionalità che né Java né Python hanno: double-dispatch. Quando si determina quale versione di un metodo Java sovraccarico chiamare da un'istruzione python, il runtime esaminerà i tipi effettivi dei parametri della chiamata e selezionerà la versione in modo dinamico. In Java i metodi sovraccaricati sono invece associati alle chiamate in fase di compilazione, che è tecnicamente polimorfico ma in un modo davvero poco interessante. L'overloading a doppia spedizione può essere effettivamente utilizzato per implementare alcuni effetti interessanti. Mi aspetto che funzioni in modo analogo in IronPython e richiami le librerie C #.

Penso di aver coperto la maggior parte delle basi qui. I commenti sono benvenuti per funzionalità aggiuntive che potrebbero essere considerate polimorfiche. Una cosa di cui non sono sicuro è la possibilità di creare proprietà / metodi sintetici o virtuali usando __getattr__ o __setattr__ et al. Inoltre, penso che potresti rendere l'argomento che il passaggio dei riferimenti ai metodi è un tipo di polimorfismo, ma forse questo sta allungando un po 'troppo le cose.

    
risposta data 09.11.2016 - 19:31
fonte
2

Non ho letto l'articolo, ma darò uno scatto.

Python è una lingua con caratteri dinamici . Quando gli accademici parlano di tipi, stanno parlando delle lingue staticamente digitate , salvo diversa indicazione. La digitazione dinamica e statica condivide molti degli stessi obiettivi, ma i metodi per raggiungere questi obiettivi sono molto diversi - in quanto tali, ciò che si applica a uno non si applica necessariamente all'altro.

Questo è il caso qui. Python usa in modo specifico tipizzazione anatra , il che significa che qualsiasi operazione che può essere eseguita, sarà eseguita.

Per elaborare, ciò significa che l'espressione a.foo avrà esito positivo se l'oggetto a ha un metodo foo , indipendentemente da quale a sia effettivamente . Il polimorfismo parametrico e sottotipo è privo di significato nel contesto della digitazione anatra.

Python supporta alcuni tipici operatori coercizione . Non conosco l'elenco completo di essi, ma ad esempio l'espressione 5 + 1.2 è valida, poiché l'intero 5 verrà convertito nel numero in virgola mobile 5.0 .

Il polimorfismo ad-hoc attraverso l'overloading di funzioni non è possibile in Python.

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

Questa non è una classificazione del polimorfismo. È solo una digitazione dinamica e statica con un nome diverso; la tipizzazione dinamica utilizza il polimorfismo di runtime (se presente) e la tipizzazione statica utilizza il polimorfismo in fase di compilazione.

    
risposta data 09.11.2016 - 17:44
fonte