Forum >> Principianti >> Chiarimento Ereditarietà Python

Pagina: 1

Ciao, scrivo ancora a distanza di pochi giorni dal mio primo post perché ho qualche problema a capire l'ereditarietà in Python, gli esempi trovati in rete mi hanno solo confuso di più. Vengo al dunque.



Prendendo spunto da un altro sito in cui ho fatto delle ricerche, diciamo che voglio creare una classe "Persona", che identifichi le persone per nome e cognome e, all'occorrenza, ne stampi i dati.

class Persona:
    def __init__(self, Nome="", Cognome=""):
        self.Nome = Nome
        self.Cognome = Cognome
    def __str__(self):
        return str(self.Nome) + " " + str(self.Cognome)

Class Studente(Persona):
    pass
Ora diciamo che io voglio creare una classe "Studente". Essendo gli studenti delle persone, creerò la classe Studente come ereditaria (si dice così??) della classe Persona. Questa classe avrà come unica aggiunga la possibilità di stampare su schermo (oltre a nome e cognome) la classe di appartenenza dello studente (Terza media, prima superiore etc..).

Qualcuno potrebbe indicarmi la giusta sintassi per definire questa classe? Oltre la prima stringa definita nel codice non so davvero come continuare :thinking:
Facciamo un esempio. Supponiamo di avere due classi come le sottostanti:
class Persona:
    '''Classe che identifica qualunque persona.'''
    def __init__(self, Nome, Cognome):
        self.Nome = Nome
        self.Cognome = Cognome
    def __str__(self):
        return "Nome: " + str(self.Nome) + "\nCognome: " + str(self.Cognome)

class Studente:
    '''Classe che identifica uno studente.'''
    def __init__(self, Nome, Cognome, Scuola):
        self.Nome = Nome
        self.Cognome = Cognome
        self.Scuola = Scuola
    def __str__(self):
        return "Nome: " + str(self.Nome) + "\nCognome: " + str(self.Cognome) + "\nScuola: " + str(self.Scuola)
Studente ha molto in comune con Persona, allora perché non riutilizzare parte del codice introducendo proprio l'ereditarietà?

Lasciamo la classe Persona così com'è, ma lavoriamo su Studente:
class Studente(Persona):
    '''Classe che identifica uno studente.'''
    def __init__(self, Nome, Cognome, Scuola):
        self.Scuola = Scuola
        Persona.__init__(self, Nome, Cognome)
    def __str__(self):
        return Persona.__str__(self) + "\nScuola:" + str(self.Scuola)
Così credo che ottieni quello che chiedi, almeno spero.
>>> max = Persona("Max","Power")
>>> print(max)
Nome: Max
Cognome: Power
>>> max_student = Studente("Max","Power","Bosh Institute")
>>> print(max_student)
Nome: Max
Cognome: Power
Scuola: Bosh Institute
Ciao e buon anno.
Daniele
Si, era esattamente ciò che mi interessava. Grazie mille e buon anno anche a te :)
Si, era esattamente ciò che mi interessava. Grazie mille e buon anno anche a te :)
Non voglio farti casino, ma solo completare l'informazione. Esiste anche la possibilità, se usi Python 3, di usare super() per me una meraviglia assoluta.

L'esempio sopra diventa:
class Studente(Persona):
    '''Classe che identifica uno studente.'''
    def __init__(self, Nome, Cognome, Scuola):
        self.Scuola = Scuola
        super().__init__(Nome, Cognome)
    def __str__(self):
        return super().__str__() + "\nScuola:" + str(self.Scuola)
In questo caso super() viene usata senza argomenti, ma è esattamente equivalente a super(Studente, self) che come avrai intuito chiama i metodi della classe padre, Persona nel nostro caso.

Confessa, ti ho stupito? ;)

Cya
Scusa se rispondo solo ora, non stavo seguendo più la conversazione convinto che ormai fosse terminata :D In realtà uso ancora la versione 2.7, non essendo un mostro in inglese le uniche guide trovate in italiano finora si fermano a quella (fatta eccezione per alcune che trovo molto poco per principianti). Grazie per l'info comunque :D Ora che ci sei vorrei porti una domanda, ti prego di non fucilarmi nel caso stia dicendo blasfemie.
L'ereditarietà, di preciso, quali vantaggi ha? Ok, la classe della discussione è di una semplicità disarmante e forse questo è un caso isolato, ma se prendiamo in esame il codice che tu mi hai scritto, qual è la differenza tra lo scrivere la classe "Studente" come ereditaria della classe "Persona" invece che riscriverla come classe a sé?

Noto che la parte di codice precedente deve essere comunque riscritta, sia nel corpo della classe, sia nell'invocazione. Scusa se la domanda può sembrare stupida ma non ci arrivo :/
Si sono scritti interi "romanzi" sull'ereditarietà, ed i concetti non valgono solo per Python, ma in generale dovunque si possa utilizzare questo paradigma di programmazione. Nei nostri esempi il codice era davvero molto banale, ma non sarà sempre così. In generale poter riutilizzare codice già scritto ed ereditare i metodi dalla classe principale, non hanno prezzo.

Pensare da Informatico, libro scritto parecchi anni fa, da questa definizione di ereditarietà: La caratteristica più frequentemente associata alla programmazione ad oggetti è l'ereditarietà che è la capacità di definire una nuova classe come versione modificata di una classe già esistente. Il vantaggio principale dell'ereditarietà è che si possono aggiungere nuovi metodi ad una classe senza dover modificare la definizione originale. È chiamata "ereditarietà" perché la nuova classe "eredita" tutti i metodi della classe originale. Estendendo questa metafora la classe originale è spesso definita "genitore" e la classe derivata "figlia" o "sottoclasse". L'ereditarietà è una caratteristica potente e alcuni programmi possono essere scritti in modo molto più semplice e conciso grazie ad essa, dando inoltre la possibilità di personalizzare il comportamento di una classe senza modificare l'originale. Il fatto stesso che la struttura dell'ereditarietà possa riflettere quella del problema può rendere in qualche caso il programma più semplice da capire.

Mettendo però l'utente anche in guardia: D'altro canto l'ereditarietà può rendere più difficile la lettura del programma, visto che quando si invoca un metodo non è sempre chiaro dove questo sia stato definito (se all'interno del genitore o delle classi da questo derivate) con il codice che deve essere rintracciato all'interno di più moduli invece che essere in un unico posto ben definito. Molte delle cose che possono essere fatte con l'ereditarietà possono essere di solito gestite elegantemente anche senza di essa, ed è quindi il caso di usarla solo se la struttura del problema la richiede: se usata nel momento sbagliato può arrecare più danni che apportare benefici.
Daniele aka Palmux said @ 2017-01-02 22:57:28:
Mettendo però l'utente anche in guardia: D'altro canto l'ereditarietà può rendere più difficile la lettura del programma, visto che quando si invoca un metodo non è sempre chiaro dove questo sia stato definito (se all'interno del genitore o delle classi da questo derivate) con il codice che deve essere rintracciato all'interno di più moduli invece che essere in un unico posto ben definito. Molte delle cose che possono essere fatte con l'ereditarietà possono essere di solito gestite elegantemente anche senza di essa, ed è quindi il caso di usarla solo se la struttura del problema la richiede: se usata nel momento sbagliato può arrecare più danni che apportare benefici.
Parla di ⓏZope™, credo. :P


THE 🍺-WARE LICENSE (Revision ㊷):
<carlo@🐍.it> wrote this post. As long as you retain this notice you
can do whatever you want with this stuff. If we meet some day, and you
think this stuff is worth it, you can buy me a 🍺 in return. -- ㎝
Si, era esattamente ciò che mi interessava. Grazie mille e buon anno anche a te :)
Si, molto chiaro.

:ok:


Pagina: 1



Esegui il login per scrivere una risposta.