Skip to content

5. Classi e oggetti

Una classe è il modello da cui vengono creati gli oggetti. Si dice che un oggetto sia un'istanza di una classe.

  

5.1. Una classe oggetto


Programma (classes_01)

#   -*- coding=utf-8 -*-

class Objet:
    """une classe Objet vide"""

#   any variable can have attributes by construction
obj1=Objet()
obj1.attr1="un"
obj1.attr2=100
#  displays the
print "objet1=[{0},{1}]".format(obj1.attr1,obj1.attr2)
#   modify object
obj1.attr2+=100
#  displays the
print "objet1=[{0},{1}]".format(obj1.attr1,obj1.attr2)
#   assigns object1 reference to object2
obj2=obj1
#   modify obj2
obj2.attr2=0
#   displays both objects
print "objet1=[{0},{1}]".format(obj1.attr1,obj1.attr2)
print "objet2=[{0},{1}]".format(obj2.attr1,obj2.attr2)

Note:

  • riga 4: un'altra forma di commento. Preceduto da tre "", può estendersi su più righe;
  • righe 3-4: una classe oggetto vuota;
  • riga 7: istanziazione della classe Object;
  • riga 17: copia di riferimento. Le variabili obj1 e obj2 sono due puntatori (riferimenti) allo stesso oggetto.

Risultati

1
2
3
4
objet1=[un,100]
objet1=[un,200]
objet1=[un,0]
objet2=[un,0]

5.2. Una classe Person


Programma (classes_02)

#    -*- coding=utf-8 -*-

class Personne:
    #    class attributes
    #    undeclared - can be created dynamically

    #    method
    def identite(self):
        #    a priori, uses non-existent attributes
        return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)

#    ---------------------------------- main
#  attributes are public and can be created dynamically
p=Personne()
p.prenom="Paul"
p.nom="Langevin"
p.age=48
#    method call
print "personne={0}\n".format(p.identite())

Note:

  • righe 3-10: una classe con un metodo;
  • Riga 8: ogni metodo in una classe deve avere l'oggetto self — che fa riferimento all'oggetto corrente — come primo parametro.

Risultati

personne=[Paul,Langevin,48]

5.3. La classe Person con un costruttore


Programma (classes_03)

#   -*- coding=utf-8 -*-

class Personne:

    #   manufacturer
    def __init__(self,prenom,nom,age):
        self.prenom=prenom;
        self.nom=nom;
        self.age=age;

    #   method
    def identite(self):
        #   a priori, uses non-existent attributes
        return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)

#   ---------------------------------- main
#   a Person object
p=Personne("Paul","Langevin",48)
#   method call
print "personne={0}\n".format(p.identite())

Note:

  • riga 6: il costruttore della classe si chiama __init__. Come per gli altri metodi, il suo primo parametro è self;
  • riga 18: un oggetto Person viene creato utilizzando il costruttore della classe.

Risultati

personne=[Paul,Langevin,48]

5.4. La classe Person con controlli di validità nel costruttore


Programma (classes_04)

#    -*- coding=utf-8 -*-

import re

# -------------------
#    a proprietary exception class
class MyError(Exception):
    pass

class Personne:

    #    manufacturer
    def __init__(self,prenom="x",nom="x",age=0):
         #  first name must be non-empty
        match=re.match(r"^\s*(\S+)\s*$",prenom)
        if not match:
            raise MyError("Le prenom ne peut etre vide")
        else:
            self.prenom=match.groups()[0]
        #  name must be non-empty
        match=re.match(r"^\s*(\S+)\s*$",nom)
        if not match:
            raise MyError("Le nom ne peut etre vide")
        else:
            self.nom=match.groups()[0]
        #  age must be valid
        match=re.match(r"^\s*(\d+)\s*$",str(age))
        if not match:
            raise MyError("l'age doit etre un entier positif")
        else:
            self.age=match.groups()[0]

    def __str__(self):
        return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)

#    ---------------------------------- main
#    a Person object
try:
    p=Personne("  Paul  ","  Langevin  ",48)
    print "personne={0}".format(p)
except MyError, erreur:
    print erreur
#    another object Nobody
try:
    p=Personne("  xx  ","  yy  ","  zz")
    print "personne={0}".format(p)
except MyError, erreur:
    print erreur
#    another person
try:
    p=Personne()
    print "personne={0}".format(p)
except MyError, erreur:
    print erreur

Note:

  • righe 7-8: una classe MyError derivata dalla classe Exception. Non aggiunge alcuna funzionalità a quest'ultima. È presente solo per fornire un'eccezione personalizzata;
  • Riga 13: il costruttore ha valori predefiniti per i suoi parametri. Pertanto, l'operazione p = Person() è equivalente a p = Person("x", "x", 0);
  • Righe 15–9: viene verificato il parametro first_name. Non deve essere vuoto. Se lo è, viene generata l'eccezione MyError con un messaggio di errore;
  • Righe 21–25: Lo stesso vale per il parametro last_name;
  • righe 27–31: verifica dell'età;
  • righe 33-34: la funzione __str__ sostituisce il metodo precedentemente chiamato identite;
  • righe 38–42: istanziare una Person e visualizzarne l'identità;
  • riga 39: istanziazione;
  • riga 40: visualizzazione. L'operazione richiede la visualizzazione della persona p come stringa. L'interprete Python chiama quindi automaticamente il metodo p.__str__() se esiste. Questo metodo ha lo stesso scopo del metodo toString() nei linguaggi Java o .NET;
  • righe 41–42: gestione di una potenziale eccezione MyError. Quindi visualizza il messaggio di errore associato all'eccezione;
  • righe 44–48: come sopra per una seconda istanza di Person creata con parametri errati;
  • righe 50–54: come sopra per una terza istanza di Person creata con i parametri predefiniti.

Risultati

1
2
3
personne=[Paul,Langevin,48]
l'age doit etre un entier positif
personne=[x,x,0]

5.5. Aggiunta di un metodo che funge da secondo costruttore


Programma (classes_05)

#    -*- coding=utf-8 -*-

import re

# -------------------
#    a proprietary exception class
class MyError(Exception):
    pass

class Personne:
    #    class attributes
    #    undeclared - can be created dynamically

    #    manufacturer
    def __init__(self,prenom="x",nom="x",age=0):
         #  first name must be non-empty
        match=re.match(r"^\s*(\S+)\s*$",prenom)
        if not match:
            raise MyError("Le prenom ne peut etre vide")
        else:
            self.prenom=match.groups()[0]
        #  name must be non-empty
        match=re.match(r"^\s*(\S+)\s*$",nom)
        if not match:
            raise MyError("Le nom ne peut etre vide")
        else:
            self.nom=match.groups()[0]
            #  age must be valid
        match=re.match(r"^\s*(\d+)\s*$",str(age))
        if not match:
            raise MyError("l'age doit etre un entier positif")
        else:
            self.age=match.groups()[0]

    def initWithPersonne(self,p):
        #  initializes the current object with a person p
        self.__init__(p.prenom,p.nom,p.age)

    def __str__(self):
        return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)

#    ---------------------------------- main
#    a Person object
try:
    p0=Personne("  Paul  ","  Langevin  ",48)
    print "personne={0}".format(p0)
except MyError, erreur:
    print erreur
#    another object Nobody
try:
    p1=Personne("  xx  ","  yy  ","  zz")
    print "personne={0}".format(p1)
except MyError, erreur:
    print erreur
#    another person
p2=Personne()
try:
    p2.initWithPersonne(p0)
    print "personne={0}".format(p2)
except MyError, erreur:
    print erreur

Note:

  • La differenza rispetto allo script precedente si trova alle righe 35–37. Abbiamo aggiunto il metodo initWithPerson. Questo metodo richiama il costruttore \_\_init\_\_. A differenza dei linguaggi tipizzati, non è possibile avere metodi con lo stesso nome che si distinguano per la natura dei loro parametri o dei loro valori di ritorno. Pertanto, non è possibile avere più costruttori che creino l'oggetto a partire da parametri diversi, in questo caso un oggetto di tipo Person.

Risultati

1
2
3
personne=[Paul,Langevin,48]
l'age doit etre un entier positif
personne=[Paul,Langevin,48]

5.6. Un elenco di oggetti Person


Programma (classes_06)

#   -*- coding=utf-8 -*-

class Personne:
    ...

#   ---------------------------------- main
#   create a list of person objects
groupe=[Personne("Paul","Langevin",48), Personne("Sylvie","Lefur",70)]
#  identity of these persons
for i in range(len(groupe)):
  print "groupe[{0}]={1}".format(i,groupe[i])

Note:

  • Righe 3-5: la classe Person già descritta

Risultati

groupe[0]=[Paul,Langevin,48]
groupe[1]=[Sylvie,Lefur,70]

5.7. Creazione di una classe derivata dalla classe Person


Programma (classes_07)

#    -*- coding=utf-8 -*-

import re

class Personne:
    ...

class Enseignant(Personne):
    def __init__(self,prenom="x",nom="x",age=0,discipline="x"):
        Personne.__init__(self,prenom,nom,age)
        self.discipline=discipline

    def __str__(self):
        return "[{0},{1},{2},{3}]".format(self.prenom,self.nom,self.age,self.discipline)


#    ---------------------------------- main
#  create a list of Personne objects and derivatives
groupe=[Enseignant("Paul","Langevin",48,"anglais"), Personne("Sylvie","Lefur",70)]
#  identity of these persons
for i in range(len(groupe)):
  print "groupe[{0}]={1}".format(i,groupe[i])

Note:

  • righe 5-6: la classe Person è già definita;
  • riga 8: dichiara la classe Teacher come sottoclasse della classe Person;
  • riga 10: il costruttore della classe derivata Teacher deve chiamare il costruttore della classe padre Person;
  • righe 21-22: per visualizzare group[i], l'interprete utilizza il metodo group[i].__str__(). Il metodo __str__() utilizzato è quello della classe effettiva di group[i], come mostrato nei risultati riportati di seguito.

Risultati

groupe[0]=[Paul,Langevin,48,anglais]
groupe[1]=[Sylvie,Lefur,70]

5.8. Creazione di una seconda classe derivata dalla classe Person


Programma (classes_08)

#    -*- coding=utf-8 -*-

import re

class Personne:
    ...

class Enseignant(Personne):
    ...

class Etudiant(Personne):
    def __init__(self,prenom="x",nom="x",age=0,formation="x"):
        Personne.__init__(self,prenom,nom,age)
        self.formation=formation

    def __str__(self):
        return "[{0},{1},{2},{3}]".format(self.prenom,self.nom,self.age,self.formation)

#    ---------------------------------- main
#  create a list of Personne objects and derivatives
groupe=[Enseignant("Paul","Langevin",48,"anglais"), Personne("Sylvie","Lefur",70), Etudiant("Steve","Boer",22,"iup2 qualite")]
#  identity of these persons
for i in range(len(groupe)):
  print "groupe[{0}]={1}".format(i,groupe[i])

Note:

  • Questo script è simile al precedente.

Risultati

groupe[0]=[Paul,Langevin,48,anglais]
groupe[1]=[Sylvie,Lefur,70]
groupe[2]=[Steve,Boer,22,iup2 qualite]