Anteprima
Vedrai una selezione di 5 pagine su 19
Laboratorio Informatica Pag. 1 Laboratorio Informatica Pag. 2
Anteprima di 5 pagg. su 19.
Scarica il documento per vederlo tutto.
Laboratorio Informatica Pag. 6
Anteprima di 5 pagg. su 19.
Scarica il documento per vederlo tutto.
Laboratorio Informatica Pag. 11
Anteprima di 5 pagg. su 19.
Scarica il documento per vederlo tutto.
Laboratorio Informatica Pag. 16
1 su 19
D/illustrazione/soddisfatti o rimborsati
Disdici quando
vuoi
Acquista con carta
o PayPal
Scarica i documenti
tutte le volte che vuoi
Estratto del documento

PARAMETRI OPZIONALI

Nei parametri formali di una funzione possono essere inseriti anche dei parametri opzionali:

Esempio: Utilizzo: Viene utilizzato il

def interessi(capitale, tasso=0.05): >>>s=interessi(100) valore di default

i=capitale*tasso >>>print(s) se non è specificato

return i 5 il parametro opzionale

c = interessi(prestito) >>>print(interessi(100, tasso=0.12))

… 12

Valore di default Nell’invocazione di una

del parametro funzione, i parametri

opzionali vanno sempre

opzionale per ultimi

Data una funzione: def fun1(par1, par2, opz1=100, opz2=False):

……

I parametri attuali vanno disposti in questo modo: >>>a=fun1(10, 20, opz2=True, opz1=2)

i parametri obbligatori vengono mappati sulla base della posizione

 Namespace:

i parametri opzionali vengono mappati in base al nome citato

 par1=10

par2=20

opz1=2

opz2=True

METODI PARAMETRI OPZIONALI

I parametri opzionali possono essere usati sia nelle funzioni sia nei metodi degli oggetti.

Es. def open(filename, mode, encoding=‘ascii’, errors=‘ignore’)

#codice

Es. uso dei parametri opzionali nei metodi : Class CsvReader4:

def __init__(self, fname):

self.f=open(fname,'r’)

def readRecord(self, sep=‘;’):

line = self.f.readline()

if line=='':

return []

else:

line = line.strip('\n')

records = line.split(sep)

return records

cr = CsvReader4('prova.csv')

r=cr.readRecord()

while r!=[]:

print(r)

r=cr.readRecord()

EREDITARIETA’

L’ereditarietà rappresenta una relazione tra :

– Una superclasse (classe padre), più generica

– Una sottoclasse (classe figlia), più specifica

La classe figlia eredita i dati (attributi) e il comportamento

(metodi) dalla classe padre.

Vantaggi:

• Il vantaggio dell’ereditarietà è quello di condividere parti di codice

• Permette di rappresentare oggetti aventi comportamenti diversi

Spesso la diversità tra oggetti può essere espressa con una semplice variabile di oggetto, in questo

caso non serve l’ereditarietà.

Esempio:

– Se due veicoli differiscono solo per il consumo di benzina, usa una variabile di oggetto (es. kmPerLitro)

– Se due veicoli si comportano in modo differente, usa l’ereditarietà (es. auto e camion)

SOTTOCLASSE

In Python si definisce una sottoclasse specificando cosa la rende diversa dalla sua superclasse.

Le sottoclassi ereditano dalla superclasse: – tutte le variabili di oggetto

– tutti i metodi che non si modificano

La sottoclasse può aggiungere: – Variabili nuove (non presenti nella superclasse)

– Metodi nuovi (non presenti nella superclasse)

– Metodi che modificano il comportamento di metodi ereditati

(sovrascrivono = override)

Esempio:

class Animale: #classe padre

def __init__(self, nome): • def class Figlia(Padre):

self.nome = nome La classe Figlia eredita dalla classe Padre tutto.

def parla(self): es.: – il costruttore,

print(“”) – l’attributo self.nome

class Gatto(Animale): #classe figlia

def parla(self): #overriding

print("Miao!”) • Overriding: quando una classe Figlia ridefinisce

class Cane(Animale): #classe figlia un metodo della classe Padre

def parla(self): #overriding Es., il metodo parla()

print("Bau!”)

g = Gatto("Garfield") • parla() e' un esempio di polimorfismo. Ha un

g.parla() #Miao! comportamento diverso a seconda dell’oggetto

c = Cane("Rocky") su cui viene invocato.

c.parla() #Bau!

COSTRUTTORE DELLA SOTTOCLASSE In Python 2:

nomeSuperclasse.__init__(self,

parametri)

In Python 3:

super() .__init__(parametri)

METODI DELLA SOTTOCLASSE : OVERRIDING e OVERLOADING

Metodi di una sottoclasse ereditati dalla superclasse si comportano nello stesso modo

Se volete modificare il comportamento di un metodo

– Scrivete un metodo nella sottoclasse con stesso nome, stessi parametri, ma nuova implementazione

– Questo metodo sovrascrive il metodo della superclasse

Il nuovo metodo sarà invocato con lo stesso nome quando è chiamato su un oggetto della sottoclasse

OVERLOADING = creazione di un metodo con stesso nome e parametri diversi

I linguaggi ad oggetti (es. Java, C++) permettono di creare in una classe diverse versioni dello stesso metodo

(stesso nome, diversi parametri).

In python quando si crea un metodo con lo stesso nome di un metodo precedente, il metodo precedente

viene sovrascritto in Python questo metodo non è ammesso.

Esempio: class CsvReader3:

class CsvReaderSbagliato: ma può essere simulato

 def __init__(self, fname):

def __init__(self, fname): utilizzando parametri opzionali  self.f=open(fname,'r')

self.f=open(fname,'r') def readRecord(self, sep=‘;’):

def readRecord(self): line = self.f.readline()

line = self.f.readline() if line=='':

if line==””: return []

return [] else:

else: line = line.strip('\n')

line = line.strip('\n') return(line.split(';'))

return(line.split(';'))

def readRecord(self, sep): Questo metodo sovrascrive cr1 = CsvReader3('prova.csv')

line = self.f.readline() il precedente r1=cr1.readRecord() #ok

if line=='’: cr2 = CsvReader3(’dat.csv')

return [] Viene aggiunto automaticamente r2=cr2.readRecord(sep=‘,’) #ok

else: r come primo parametro del

line = line.strip('\n') metodo

return(line.split(sep)) Uso il parametro opzionale

per specificare un differente

cr = CsvReaderSbagliato('prova.txt') separatore di informazioni

r=cr.readRecord() #cerca di richiama il 1° metodo

#TypeError: readRecord() takes exactly 2 arguments (1 given)

EREDITARIETA’ MULTIPLA

class Camion(): Una classe può ereditare da più padri

def __init__(self, targa, proprietario): class Figlia(Padre1, Padre2, …):

self.targa=targa La figlia eredita tutti i metodi ed attributi delle classi padri.

self.prop=proprietario

def getNumRuote(self): La classe figlia può effettuare l’overriding di metodi,

return 6 es. getNumRuote().

def getProprietario(self):

return self.prop

class Cisterna():

def setQtTrasp(self, qt):

self.qt=qt

def getQtTrasp(self):

return self.qt

class Autocisterna(Camion, Cisterna):

def getNumRuote(self):

return 8

a=Autocisterna('DF645HK','Rossi')

a.setQtTrasp(50)

print(a.getQtTrasp()) #50

print(a.getNumRuote()) #8

print(a.getProprietario()) #Rossi

CONFLITTI

class Auto(): • Conflitto: due classi padri offrono un metodo con lo stesso nome.

def getNumRuote(self): Ma in python, può esistere un solo metodo con lo stesso nome.

return 4

def getNumPosti(self): • Criteri di scelta del metodo che la figlia erediterà (da alto al basso):

return 5 – metodo nella classe figlia che fa overriding (se presente)

– la classe padre che appare più a sinistra tra le ()

class Barca(): nella dichiarazione della classe figlia

def getLunghezza(self):

return 5 Es. getNumPosti().

def getNumPosti(self): – No overriding: in Anfibio, non è definito getNumPosti()

return 10 – getNumPosti() di Barca prevale sul metodo della classe Auto

class Anfibio(Barca, Auto):

def colore(self):

return "Rosso"

af = Anfibio()

print(af.getNumRuote()) #4

print(af.getLunghezza()) #5

print(af.getNumPosti()) #10

INCAPSULAMENTO

Interfaccia pubblica della classe = insieme di tutti i metodi della classe, e la descrizione del comportamento

Incapsulamento = è la strategia di mettere a disposizione un’interfaccia pubblica, mantenendo nascosti i

dettagli implementativi.

Es. usando un programma che è operativo da molto tempo, è normale che alcuni dettagli implementativi

siano cambiati per rendere gli oggetti più efficienti, tenendo nascosti tali dettagli i miglioramenti non

costringono chi usa il programma a fare modifiche dei dettagli implementativi.

import codecs #Gest. file tradizionale

f = codecs.open(’file.txt', ‘r’, encoding='utf-16’) f = open(’file.txt', ‘r’)

s=f.readline() s=f.readline()

f.seek(15) f.seek(15)

f.close() f.close()

Incapsulamento e Polimorfismo

– Entrambi gli oggetti condividono un’interfaccia comune (metodi readline, seek, close …)

– Diversa implementazione

– Comportamento diverso a seconda del contesto

(scrivere/posizionarsi su un file UTF16 è diverso dallo scrivere/posizionarsi su un file ASCII)

ENCAPSULATION: PROBLEMA

Esempio: Il programma utilizzatore della class Studente ha avuto accesso alla struttura dati interna della classe.

La struttura dati interna della classe è cambiata MA non è stato adeguato il codice del programma utilizzatore.

class Studente():

def __init__(self, nome):

self.nome = nome con s.nome accedo

direttamente all'attributo

s=Studente("Mario Rossi")

print(s.nome.upper()) #MARIO ROSSI s.nome è una stringa

#Modifico la classe Studente su cui posso richiamare il

class Studente(): metodo upper()

def __init__(self, nome):

self.nome = nome.split(' ')

s=Studente("Mario Rossi")

print(s.nome.upper()) AMO FOLLEMENTE GIOGOTTA E LO SPOSERO’

#AttributeError: 'list' object has no attribute 'upper' class Studente2():

RISOLVO IL PROBLEMA class Studente2(): def __init__(self, nome):

def __init__(self, nome): self._nome = nome.split(’ ‘)

self._nome = nome def getNome(self):

def getNome(self): st=""

return self._nome for el in self._nome:

st=st+el+' '

Le modifiche al codice sono frequenti, per modificare return st

(tutti) i programmi che utilizzano una classe

modificando solo la classe uso l’encapsulation.

 s=Studente2("Mario Rossi")

print(s.getNome().upper()) #MARIO ROSSI

ENCAPSULATION

Si creano dei metodi per accedere ai dati: cioè un’interfaccia, progettata per rimanere inalterata nel tempo.

class Studente2():

def __init__(self, nome):

def getNome(self):

Nascondi le strutture dati e le implementazioni sottostanti. L’obiettivo è quello di forzare l’accesso ai dati

attraverso i metodi dell’interfaccia.

Per nascondere gli attributi INFORMATION HIDING

Convenzione: non si accede dall’esterno di una classe agli attributi o metodi il cui nome inizia con _

E’ usato per indicare attributi che saranno modificati a breve; essendo una convenzione può essere disattes

Dettagli
Publisher
A.A. 2017-2018
19 pagine
4 download
SSD Scienze matematiche e informatiche INF/01 Informatica

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher aina.belloni di informazioni apprese con la frequenza delle lezioni di Laboratorio di informatica e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Università degli Studi di Milano - Bicocca o del prof Boselli Roberto.