Classi python

12
24/2/2015 Fondamenti di Programmazione http://pellacini.di.uniroma1.it/teaching/fondamenti14/lectures/lecture12/notes.html 1/12 CLASSI In questa lezione vedremo come si possono introdurre nuovi tipi in Python tramite il costrutto class . L'utilità di introdurre nuovi tipi è illustrata riscrivendo esempi di image processing tramite le classi. CLASSI Python come molti altri linguaggi object oriented permette di introdurre nuovi tipi tramite il concetto di classe. Una classe è la definizione di un tipo i cui valori sono oggetti che hanno uno stato e che possono avere delle operazioni (metodi) che possono essere eseguite su di essi. Ad esempio, tutti i tipi di Python ( int , float , str , ecc.) sono definiti tramite classi e tutte le operazioni o metodi che possono essere eseguiti su di essi sono definiti nella loro classe. L'uso delle classi non è necessario per risolvere nuovi problemi. Ma tipicamente rende il codice più chiaro perché le classi permettono allo stesso tempo di definire il significato (tipo) di un oggetto e le operazioni (metodi) definite su questo, nascondendo in qualche caso i dettagli su come queste operazioni sono definite. Al contrario, usare tipi di base e funzioni porta ad essere molto più espliciti e a ricordarci più dettagli durante la programmazione (ad esempio che un colore è una tupla (r,g,b) invece semplicemente di ricordarci che un colore è un oggetto di tipo Colore ). Inizieremo con un esempio molto semplice di una classe Color che rappresenta un generico colore. Specificheremo che un colore ha tre variabili r , g e b , che lo rappresentano e ha metodi che sono operazioni definite su di esso (come inverse ). Ogni oggetto di tipo Color rappresenta un colore specifico, ad esempio nero o bianco, determinato assegnando opportuni valori alle tre variabili. Per definire una classe in Python la sintassi è la seguente: class NomeTipo(object): # object è una parola chiave definizione dei metodi Quindi la parola chiave class seguita dal nome che si vuole dare al nuovo tipo (per convenzione dovrebbe iniziare con una lettera maiuscola) e dopo i : e indentati le definizioni dei metodi del tipo NomeTipo .

description

Classi python

Transcript of Classi python

  • 24/2/2015 FondamentidiProgrammazione

    http://pellacini.di.uniroma1.it/teaching/fondamenti14/lectures/lecture12/notes.html 1/12

    CLASSIInquestalezionevedremocomesipossonointrodurrenuovitipiinPythontramiteilcostrutto class .L'utilitdiintrodurrenuovitipiillustratariscrivendoesempidiimageprocessingtramiteleclassi.

    CLASSIPythoncomemoltialtrilinguaggiobjectorientedpermettediintrodurrenuovitipitramiteilconcettodiclasse.Unaclasseladefinizionediuntipoicuivalorisonooggettichehannounostatoechepossonoaveredelleoperazioni(metodi)chepossonoessereeseguitesudiessi.Adesempio,tuttiitipidiPython( int ,float , str ,ecc.)sonodefinititramiteclassietutteleoperazioniometodichepossonoessereeseguitisudiessisonodefinitinellaloroclasse.

    L'usodelleclassinonnecessarioperrisolverenuoviproblemi.Matipicamenterendeilcodicepichiaroperchleclassipermettonoallostessotempodidefinireilsignificato(tipo)diunoggettoeleoperazioni(metodi)definitesuquesto,nascondendoinqualchecasoidettaglisucomequesteoperazionisonodefinite.Alcontrario,usaretipidibaseefunzioniportaadesseremoltopiesplicitiearicordarcipidettaglidurantelaprogrammazione(adesempiocheuncoloreunatupla (r,g,b) invecesemplicementediricordarcicheuncoloreunoggettoditipo Colore ).

    Inizieremoconunesempiomoltosemplicediunaclasse Color cherappresentaungenericocolore.Specificheremocheuncolorehatrevariabili r , g e b ,chelorappresentanoehametodichesonooperazionidefinitesudiesso(come inverse ).Ognioggettoditipo Color rappresentauncolorespecifico,adesempioneroobianco,determinatoassegnandoopportunivalorialletrevariabili.

    PerdefinireunaclasseinPythonlasintassilaseguente:

    class NomeTipo(object): # object una parola chiave definizione dei metodi

    Quindilaparolachiave class seguitadalnomechesivuoledarealnuovotipo(perconvenzionedovrebbeiniziareconunaletteramaiuscola)edopoi : eindentatiledefinizionideimetodideltipo NomeTipo .

  • 24/2/2015 FondamentidiProgrammazione

    http://pellacini.di.uniroma1.it/teaching/fondamenti14/lectures/lecture12/notes.html 2/12

    ATTRIBUTIInPython,levariabilieimetodidefinitiinunaclassesonospessochiamatiattributi,nelsensochespecificanodeivaloriodelleoperazionichesono"attaccati"aglioggettidellaclasse.Ivaloridialcuniattributispessosonospecificatinelmomentoincuiunoggettodellaclassevienecreato.Perfarecic'unmetodospeciale,dettocostruttore,conilnome __init__ .Ilcostruttoreusatoperinizializzarelostatodell'oggettochestaperesserecreato.

    class NomeTipo(object): def __init__(self, argomenti...): self.nome_variabile1 = valore1 ...

    Vediamocomedefinirelaclasse Color conattributi r , g e b :

    class Color(object): def __init__(self, r, g, b): self.r = r self.g = g self.b = b

    Ilparametro self unparametrospecialechedevesempreessereilprimoparametrodiunmetododellaclasse.Pythonassegnaautomaticamentealparametro self l'oggettorelativamentealqualeilmetodostatochiamato,quindinondeveesserespecificatoquandosichiamaunmetodo.Nelcasodelcostruttoreilvaloredi self el'oggettochesistacostruendo.Lasintassidel . ,comegisappiamo,permettediaccedereaicosidettiattributidiunoggettochepossonoesseremetodiovariabili.Nelcasodi self.r , self.g eself.b sonovariabilichecontengonovalorinumerici.

    OGGETTIPerusareunaclasse,creiamooggettidiqueltipo.Glioggettisicreanochiamandoilconstruttore,che,essendounmetodospeciale,sichiamaconunasintassias.Inquestocosachiameremoilnomedellaclasseconiparametrichevogliamopassarealcostruttore.

    oggetto = NomeTipo(parametri...)

    L'oggettoadessocreatosardeltipodellaclasseepotremmoaccedereallesuevariabiliutilizzandolanotazionedelpunto.

  • 24/2/2015 FondamentidiProgrammazione

    http://pellacini.di.uniroma1.it/teaching/fondamenti14/lectures/lecture12/notes.html 3/12

    >>> c1 = Color(255,0,0)>>> type(c1)

    >>> c1.r255>>> c1.g0>>> c1.b0

    Secreiamodueoggettidellastessotipo,avremocheiltipolostesso,mailvalorememorizzatonellerispettivevariabilipuesserediverso.

    >>> c2 = Color(0,255,0)>>> c2.r0>>> c2.g255>>> c2.b0

    >>> type(c2)

    >>> id(c1)4396694096>>> id(c2)4396694224

    Seaccediamoavariabilinonesistenti,otteniamounerrore.

    >>> c1.zTraceback (most recent call last): File "", line 1, in c1.z AttributeError: 'Color' object has no attribute 'z'

    Ingenerale,glioggettiinPythonsonomutabili,ciopossiamodirettamenteaccedereallavariabiliemodificarle.Questomodificherilvalorediquellavariabilesoloperl'oggettochelacontiene,nonperglialtri.

    >>> c1.g = 128>>> c1.g128>>> c2.g

  • 24/2/2015 FondamentidiProgrammazione

    http://pellacini.di.uniroma1.it/teaching/fondamenti14/lectures/lecture12/notes.html 4/12

    255

    Perchiarezza,visualizziamoilcomportamentonelvisualizzatore.

    # definiamo la classeclass Color(object): def __init__(self,r,g,b): self.r = r self.g = g self.b = b

    # creiamo un Color e impostiamolo a rossoc1 = Color(255,0,0)

    # creiamo un altro Color e impostiamolo a verdec2 = Color(0,255,0)

    # accediamo alle variabiliprint c1.r, c1.g, c1.bprint c2.r, c2.g, c2.b

    # modifichiamo le variabilic1.r = 128print c1.r, c1.g, c1.bprint c2.r, c2.g, c2.b

    METODIOltreadefinirevariabilipossiamoanchedefiniredelleoperazionisuoggetti.Questesonodettemetodieagiscono,ingenerale,sullevariabilidell'oggettosulqualesonochiamate.ConosciamogiimetodichePythondefinisceperitipibuiltincomestringheeliste,adesempio append e split .Perdefinireunmetodo,siseguelasintassideiconstruttori.Imetodiprendonosemprecomeprimoargomentol'oggettoself sucuiagiscono:

    class NomeTipo(object): def nome_metodo(self, argomenti...): instruzioni...

    Adesempio,possiamoaggiungereunmetodoallaclasse Color checreailcoloreinversoeloritorna:

    class Color(object): def __init__(self, r, g, b):

  • 24/2/2015 FondamentidiProgrammazione

    http://pellacini.di.uniroma1.it/teaching/fondamenti14/lectures/lecture12/notes.html 5/12

    self.r, self.g, self.b = r, g, b def inverse(self): return Color(255 - self.r, 255 - self.g, 255 - self.b)

    Possiamochiamareunmetodousandolastessanotazionedelpunto,connomedelmetodoeargomenti.Comeperl'accessoallevariabili,unmetodopuesserechiamatosolamenteinrelazioneadunoggettoequindisolodopoavercreatounoggettodiqueltipo.

    >>> c = Color(255,0,0)>>> c.r, c.g, c.b(255, 0, 0)>>> ci = c.inverse()>>> ci.r, ci.g, ci.b(0, 255, 255)

    METODI SPECIALIAlcunimetodihannonomispecialicaratterizzatidalfattocheinizianoefinisconocondueunderscore __ .Questiservonoadefinireilcomportamentodeltiporelativamenteavarioperatori( + , in , str ,ecc.).Neabbiamogivistouno,ilconstruttorechepermettediinizializzareglioggettidiunaclasse.Cisonomoltialtrimetodispecialispecialmethodschepermettonodidarealleclassiscrittedall'utenteuncomportamentosimileaquellodeitipibuiltindiPython.Questomoltoutileperestendereillinguaggioeadattarloallarisoluzionedeiproblemipidiversi.Adesempio,perstampareoperoperaresuicolori,senzadefiniremetodispeciali,dobbiamoaccedereallevariabiliinmodoesplicito:

    # definiamo due colori>>> c1 = Color(255,0,0)>>> c2 = Color(0,255,0)# proviamo a stamparli>>> print c1

    >>> print c1.r, c1.g, c1.b255 0 0# proviamo a sommarli>>> c3 = c1 + c2Traceback (most recent call last): File "", line 1, in c3 = c1 + c2TypeError: unsupported operand type(s) for +: 'Color' and 'Color'# la somma non e' definita, abbiamo un errore

    Sipunotarecomelavoraresuicolori,senzaladefinizionedimetodispeciali,poconaturalerispettoaitipi

  • 24/2/2015 FondamentidiProgrammazione

    http://pellacini.di.uniroma1.it/teaching/fondamenti14/lectures/lecture12/notes.html 6/12

    builtindiPython.Nelnostroesempiopossiamodefiniredeimetodispecialiperstampareuncoloreinmodoleggibile,usando __str__ ,farelasommadiduecolori,usando __add__ emoltiplicareperunfattorecompresotra0.0e1.0,usando __mul__ :

    class Color(object): def __init__(self, r, g, b): self.r, self.g, self.b = r, g, b def inverse(self): return Color(255 - self.r, 255 - self.g, 255 - self.b) def __str__(self): return 'Color('+str(self.r)+','+str(self.g)+','+str(self.b)+')' def __add__(self,other): return Color(self.r+other.r,self.g+other.g,self.b+other.b) def __mul__(self, f): return Color(self.r*f, self.g*f, self.b*f)

    Lamoltiplicazioneperunfattoresipuusaresolamenteseilcolorel'operandodisinistra.

    >>> c1 = Color(255,0,0)>>> print c1Color(255,0,0)>>> c2 = Color(0,255,0)>>> print c2Color(0,255,0)>>> c3 = c1 + c2>>> print c3Color(255,255,0)>>> c4 = c3*0.7>>> print c4Color(178.5,178.5,0.0)

    INCAPSULAMENTOQuandousateinmodoadeguato,leclassipermettonodinascondereidettaglidicomeimetodisonoimplementati.Questoimportanteperchmiglioralaleggibilitdelcodice.Adesempio,perusarelist.append sufficientesaperecosafailmetodo,noncomelofa,ciononimportantesaperecomeilmetodoimplementato.InPythonsiusaunaconvenzionepernascondereidettagliimplementativi:tuttelevariabiliedimetodinascostiinizianocon _ .Perfareunesempiopicomplessodell'usodelleclassichedimostraanchequestoconcetto,creiamounaclasse Image checipermettedilavorarefacilmenteconleimmagini.Nelfarloreimplementeremoalcunefunzionigivistenellelezioniprecedenticomemetodidellaclasse.Percaricare,salvareevisualizzareun'immagine,continuiamoabasarcisulpacchetto image pernascondereidettaglidelformatoPNG.

  • 24/2/2015 FondamentidiProgrammazione

    http://pellacini.di.uniroma1.it/teaching/fondamenti14/lectures/lecture12/notes.html 7/12

    Iniziamodefinendounaclasse Image cheadognipixelassociaunoggetto Color .Comeconstruttore,usiamol'equivalentedellafunzione image.create .Aggiungiamopoideimetodiperritornareledimensionidell'immagine,perleggereeimpostareisingolipixeldell'immagine,perleggereesalvarel'immaginesudisco,pervisualizzarlainIPythoneperstamparesempliciinformazionisudiessa.

    import image

    class Image(object): def __init__(self, w, h): self._pixels = [] for j in range(h): row = [] for i in range(w): row.append(Color(0,0,0)) self._pixels.append(row) def width(self): return len(self._pixels[0]) def height(self): return len(self._pixels) def set_pixel(self,i,j,color): if 0

  • 24/2/2015 FondamentidiProgrammazione

    http://pellacini.di.uniroma1.it/teaching/fondamenti14/lectures/lecture12/notes.html 8/12

    Possiamooraaggiungeremetodipermodificareun'immagine,come copy e draw .Nelfarloutilizzermoimetodigidefinitinellaclasse.Notatecomeilcodicediventapileggibile(nonpitanti len e inside ),emoltomenopronoaderrori.

    class Image(object): ... def draw_quad(self, x, y, w, h, c): for j in range(y, y+h): for i in range(x, x+w): self.set_pixel(i,j,c) def draw_gradienth(self, c0, c1): for j in range(self.height()): for i in range(self.width()): u = float(i) / float(self.width()) self.set_pixel(i,j,c0*(1-u)+c1*u) def draw_gradientv(self, c0, c1): for j in range(self.height()): for i in range(self.width()): v = float(j) / float(self.height()) self.set_pixel(i,j,c0*(1-v)+c1*v) def draw_gradientq(self, c00, c01, c10, c11): for j in range(self.height()): for i in range(self.width()): u = float(i) / float(self.width()) v = float(j) / float(self.height()) self.set_pixel(i,j,c00*(1-u)*(1-v)+ c01*(1-u)*v+c10*u*(1-v)+c11*u*v)

    Inoltre,leoperazionidisommaemoltiplicazioneperunfattoredellaclasse Color permettonodiscrivereinmodomoltopisempliceimetodicheproduconoigradienti.

    Possiamopoiinvocareivarimetodi:

  • 24/2/2015 FondamentidiProgrammazione

    http://pellacini.di.uniroma1.it/teaching/fondamenti14/lectures/lecture12/notes.html 9/12

    img = Image(256,256)img.draw_quad(32,32,64,64,Color(255,128,0))img.draw_quad(160,160,64,64,Color(255,128,0))img.save('img_quad.png')

    img = Image(256,256)img.draw_gradienth(Color(255,0,0),Color(0,255,0))img.save('img_gradh.png')

    img = Image(256,256)img.draw_gradientv(Color(255,0,0),Color(0,255,0))img.save('img_gradv.png')

  • 24/2/2015 FondamentidiProgrammazione

    http://pellacini.di.uniroma1.it/teaching/fondamenti14/lectures/lecture12/notes.html 10/12

    img = Image(256,256)img.draw_gradientq(Color(255,0,0),Color(0,255,0), Color(0,0,255),Color(0,0,0))img.save('img_gradq.png')

    Inmododeltuttosimilesipossonoaggiungereanchetuttiifiltrivistiinprecedenza.

    ESERCIZIScrivereiseguentimetodi.

    1. Inversionedeicoloridell'interaimmagine,comedalezioneprecedente,usando Color.inverse .

  • 24/2/2015 FondamentidiProgrammazione

    http://pellacini.di.uniroma1.it/teaching/fondamenti14/lectures/lecture12/notes.html 11/12

    2. Contrastodeicoloridell'interaimmagine,comedalezioneprecedente,usandoleoperazioniaritmetichesuicolori.Introdurreunmetodopercorreggereicolorifuoriscala.

    3. Generaremosaici,comedalezioneprecedente,introducendounmetodopercalcolarelamediadeicoloriinunquadratinodell'immagine.

  • 24/2/2015 FondamentidiProgrammazione

    http://pellacini.di.uniroma1.it/teaching/fondamenti14/lectures/lecture12/notes.html 12/12

    4. Introdurrelacopiadipartediun'immaginesuun'altra,comedalezioneprecedente.