Denis Petriceanu - Python [PDF]

  • 0 0 0
  • Gefällt Ihnen dieses papier und der download? Sie können Ihre eigene PDF-Datei in wenigen Minuten kostenlos online veröffentlichen! Anmelden
Datei wird geladen, bitte warten...
Zitiervorschau

Python

Autor: Denis Petriceanu 2019

Contents Introducere in POO ................................................................................................... 4 Introducere in Python ................................................................................................ 6 Rechizite ................................................................................................................ 6 Variabilele si tipul lor ............................................................................................ 8 Clase în Python ....................................................................................................... 13 Obiecte Python (instanțe) ........................................................................................ 14 Cum se definește o clasă în Python ...................................................................... 14 Definirea unei clase în Python: ............................................................................ 14 Atribuiri de instanță ............................................................................................. 15 Atribute ale clasei ................................................................................................ 16 Obiecte instante ................................................................................................... 17 Metode de instanță ............................................................................................... 20 Modificarea atributelor ........................................................................................ 21 Python moștenirea simpla ........................................................................................ 22 Extinderea funcționalității unei clase de părinte ................................................... 24 Clasa părinte / copil ............................................................................................. 26 Anulează funcționalitatea unei clase de părinte .................................................... 29 Mostenirea Multipla ................................................................................................ 31 Constructori ............................................................................................................. 32

2

Destructori............................................................................................................... 34 Polimorfismul .......................................................................................................... 37 Incapsularea ............................................................................................................ 39 Structura dinamică a claselor ................................................................................... 41 Exceptii ................................................................................................................... 42 This ......................................................................................................................... 44 Bibliografie: ............................................................................................................ 45

3

Introducere in POO Programarea orientată pe obiecte, sau OOP (din engleza), este o paradigmă de programare care oferă un mijloc de structurare a programelor astfel încât proprietățile și comportamentele să fie grupate în obiecte individuale . De exemplu, un obiect ar putea reprezenta o persoană cu nume de proprietate, vârstă, adresă etc., cu comportamente precum mersul pe jos, vorbirea, respirația și alergarea. Sau un e-mail cu proprietăți cum ar fi lista de destinatari, subiectul, corpul etc. și comportamente cum ar fi adăugarea atașamentelor și trimiterea. Programarea in general se bazeaza foarte mult pe reutilizarea codului. De obicei, aceasta se realizeaza cu ajutorul functiilor. Daca ai scris deja un cod ce indeplineste o anumita sarcina, atunci il poti executa de oricate ori vrei daca il incluzi intr-o functie. In plus, o functie poate fi apelata de oriunde din cod si computerul va sti intotdeauna la ce te referi. Desigur, functiile isi au limitele lor. Ele nu stocheaza informatii cum ar fi valorile variabilelor, ceea ce inseamna ca de fiecare data cand este rulata, o functie incepe de la zero. Atunci, ce se intampla daca anumite functii si variabile se afla in stransa legatura si trebuie sa interactioneze destul de mult? Obiectele din lumea reala au doua caracteristici: stare si comportament. Lupii au stare (nume, culoare, rasa, le este foame) si comportament (urla, alearga, vaneaza). Si masinile au stare (trepte de viteza, marime, frane) si comportament (schimbarea vitezei, virarea, aplicarea franei). Comportamentul unui obiect poate fi modelat cu usurinta cu ajutorul functiilor. Dar ce se intampla atunci cand vrei sa retii starea unui obiect? Ce se intampla daca de fiecare data cand te plimbi cu bicicleta, lantul slabeste, materialul de pe sa se uzeaza cate putin, devii din ce in ce mai frustrat si apare o noua zgarietura pe ghidon? O functie nu poate face asta. O functie conduce la un singur rezultat, nu la patru, cinci sau cinci sute. Avem nevoie de o modalitate de grupare a functiilor si a variabilelor intr-un singur loc, pentru a putea interactiona intre ele. 4

Identificarea starii si a comportamentului in cazul obiectelor reale reprezinta o metoda minunata de a incepe sa gandesti in termenii programarii orientate pe obiecte. Obiectele software sunt din punct de vedere conceptual similare obiectelor lumii reale: si acestea au stare si comportament. Un obiect isi pastreaza starea in campuri (variabile in anumite limbaje de programare) si isi expun comportamentul prin metode (functii in anumite limbaje de programare). Metodele opereaza asupra starii interne a unui obiect si servesc ca mecanism primar in cazul comunicarii de la obiect la obiect. OOP modelează entități din lumea reală ca obiecte software unele date asociate cu acestea și pot efectua anumite funcții. O altă paradigmă de programare comună este programarea procedurală care structurează un program ca o rețetă prin faptul că oferă un set de pași, sub forma unor funcții și blocuri de cod, care curg secvențial pentru a finaliza o sarcină. Obiectul cheie este că obiectele se află în centrul paradigmei de programare orientate pe obiect, reprezentând nu doar datele, ci și în programarea procedurală, dar și în structura generală a programului. NOTĂ : Deoarece Python este un limbaj de programare multi-paradigmă, puteți alege paradigma care se potrivește cel mai bine problemei, combinați diferite paradigme într-un singur program și / sau comutați de la o paradigmă la alta pe măsură ce programul dvs. evoluează.

5

Introducere in Python Rechizite Un Python! Dacă încă nu ai Python, cele mai recente pachete de instalare sunt disponibile aici: http://python.org/download/ . Este de preferat Python 3, aceasta fiind cea mai nouă versiune! Nota: Pe platforme Windows, poți să adaugi Python la calea ta, astfel încăt să poată fi găsit de alte programe. Pentru a face asta, mergi în directorul tău de instalare (C:\Python33\), deschide directorul Tools, pe urmă directorul Scripts și execută fișierul win_add2path.py cu dublu clic.

Și un editor Un editor te ajută să citești și să scrii cod. Există foarte multe, și acesta este una dintre cele mai personale alegeri pe care le poate face un programator - ca un jucător de tenis care își alege racheta, sau ca un bucătar șef care își alege cuțitul preferat. Pentru început, o să vrei doar un editor simplu, ușor de utilizat și care nu te încurcă, dar este totuși eficient la scrierea de cod Python. Iată câteva sugestii:  Sublime Text: Un excelent editor care este simplu de utilizat. Scurtătura acestuia Ctrl+B îți permite să execuți imediat fișierul Python la care lucrezi. Rulează pe Windows, Mac și Linux. 6

 Geany: Un editor simplu care nu își propune să fie extrem de complicat. Disponibil pe Windows și Linux (probabil îl poți găsi în programul tău de gestiune a pachetelor).  TextMate: Unul dintre cele mai faimoase editoare pentru Mac, a fost un produs comercial dar între timp a devenit open-source.  Gedit and Kate: dacă dorești să folosești Linux cu Gnome și respectiv KDE, probabil ai deja unul dintre acestea instalat!  Komodo Edit: un editor strălucit, gratuit pentru Mac, Windows și Linux, bazat pe mai puternicul Komodo IDE. Sigur ca acestea nu sunt toate editoarele pe care le poti folosi pentru a programa in Python. De exemplu: eu folosesc Eclipse, acesta este un IDE puternic. Pentru a utiliza Python pe acest IDE ai nevoie de mai multe setari; am sa incerc sa enumar pasii intr-un mod cat mai succint posibil:  Ai nevoie sa instalezi Eclipse, pentru asta mergi pe site-ul oficial si descarca executabilul infunctie de ce platforma folosesti.  Dupa ce ai descarcat, da-i run si instaleaza-l. Acest pas se face usor, se instaleaza in modul conventional cateva „next-uri”  Acum va trebuie sa descarci PyDev din Eclipse, pentru asta mergi la: Help -> Install New Software  Introdu http://pydev.org/updates in „Work with”: spatiu.  Dupa cateva secunde doua optiuni vor aparea. Selecteaza PyDev for Eclipse. Nu selecta optiunea "PyDev Mylyn Integration".  Mergi mai departe apasand NEXT sau OK 7

 Acceptati termenii si conditiile  Cand va fi afisata caseta „Selection Nedeed” va trebui sa bifati singur Aptana Pydev  Dupa asta va urma o succesiune de ok-uri si next-uri.  Nu a mai ramas decat sa configurati PyDev. Windows – Preferences, in Preferences extindeti PyDev si selectati Interpreter-Python  Click New si setati Python32 in cazul numelui interpretorului 

Iar la interpreter executable puneti asta:

C:\Program Files\Python32\python.exe

(daca nu functioneaza puteti cauta exact locatia executabilului)

 Din nou o succesiune de Ok si Next  Asta este tot, tocmai ce ati configurat cu SUCCES IDE-ul pentru a putea programa in Python.

Variabilele si tipul lor

Nu este necesar să se declare variabilele înainte de a le folosi și nici să se declare tipul. Fiecare variabilă din Python este un obiect și, prin urmare, fiecare obiect suportă următoarele funcții:  help (obiect) - Afișează informații despre utilizarea obiectului  dir (obiect) - Afișează structura internă a obiectului - Toate metodele și toți membrii

8

Numerele sau variabilele de tip Integer Python accepta orice tip de nume, de la cele reale, la cele complexe.

a= 1

b = 1.653 c = 9 - 7j De exemplu: Ca să puteţi folosi fracţiile trebuie să importaţi modulul fractions. Pentru a utiliza numerele complexe nu este necesar importul a niciunui modul, pentru a arata care sunt numerele imaginare se foloseste j sau J. Nu există limită pentru lungimea întregilor. Pot fi oricât de lungi vreţi (trebuie doar să aveţi destulă memorie). Numerele float au o precizie de 15 zecimale, dar aveţi grijă deoarece operaţiile cu float nu sunt întotdeauna precise.

Boolean Valorile booleene apar în instrucţiunile decizionale, în loop-urile while, for, practic în orice context boolean (expresiile de la care Python aşteaptă o valoare booleană, adevarat sau fals).

1 < 2 => TRUE 2 < 1 => FALSE  Valoare booleană poate fi True sau False.  Valorile nenule sunt considerate True, iar cele nule sunt considerate False.  Din acest motiv, practic orice expresie poate fi folosită într-un context boolean.

9

Șiruri Tot ce apare între o pereche de citate unice sau duble este un șir. myString = ”cuvant” myLongString = ”Buna ziua!” Diferența dintre cele două este simplă: folosind ghilimele duble pot introduce apostroful ceea ce nu aș putea face dacă aș fi folosit citate simple deoarece apostroful nu ar fi fost considerat ca atare, ci pur și simplu un terminator de șir. Cativa Operatori Operatorii simpli pot fi aplicați atât la numere, cât și la șiruri de caractere:  a=1  b=2  c=a+b o stringHello = "hello" o stringWorld = "world" o stringHelloWorld = hello + " " + world Nu puteți utiliza operatorii între numere și șiruri de caractere: Liste Listele sunt similare vectorilor sau mulțimilor. Pot conține orice tip de variabilӑ/-e, iar numӑrul elementelor pe care ȋl conțin este variabil și nerestrictiv. Listele pot fi de asemenea iterate ȋntr-o manierӑ foarte simplӑ, dupӑ cum este prezentat ȋn exemplul de mai jos: 10

listaMea = [] listaMea.append(1)

Output:

listaMea.append("paine")

1

listaMea.append(2)

Paine

listaMea.append("mere") print(listaMea[0]) print(listaMea[1])

In acest caz atat adaugarea cat si afisarea s-a facut manual, dar aceasta se poate automatize putin prin adaugarea unul for sau while. for x in listaMea: print(x)

Output: 1 paine 2 mere

Aplicarea unui for la afisare pentru aceliasi lista. Sau mai jos a unui while: i = 0 Output: while i < len(listaMea): print(listaMea[i])

1 paine 2 mere

i += 1

In acest caz am folosti si ”len” care ne ofera lungimea listei respective. Funcții predefinite utile ȋn lucrul cu liste

 cmp( listName1, listName2) → Comparӑ elementele celor douӑ liste.  len( listName ) → Returneazӑ numӑrul de elemente din listӑ.  max( listName ) → Returneazӑ elementul din listӑ cu valoarea maximӑ.  min( listName ) → Returneazӑ elementul din listӑ cu valoarea minimӑ.

11

Metode predefinite utile ȋn lucrul cu liste

 listName.append( element ) → Insereazӑ elementul la finalul listei.  listName.count( element ) → Returneazӑ numӑrul de apariții al elementului ȋn listӑ.  listName.index( element ) → Returneazӑ indexul primei apariții a elementului ȋn listӑ.  listName.inser( index, element ) → Insereazӑ elementul la indexul indicat ȋn listӑ.  listName.pop() → Eliminӑ și returneazӑ ultimul element din listӑ.  listName.remove( element ) → Eliminӑ elementul indicat din listӑ.  listName.reverse() → Inverseazӑ ordinea elementelor din listӑ.  listName.sort( [function] ) → Sorteazӑ elementele din listӑ conform funcției indicate.

12

Clase în Python Concentrându-se mai întâi pe date, fiecare lucru sau obiect este o instanță a unei anumite clase . Structurile primitive de date disponibile în Python, cum ar fi numere, șiruri de caractere și liste, sunt concepute să reprezinte lucruri simple, cum ar fi costul unui produs, numele unui poem și, respectiv, culorile tale preferate. Dacă ați vrea să reprezentați ceva mult mai complicat? De exemplu, să presupunem că ați vrut să urmăriți mai multe animale diferite. Dacă ați folosit o listă, primul element ar putea fi numele animalului, în timp ce al doilea element ar putea reprezenta vârsta sa. De unde ar ști cine ar trebui să fie elementul? Dacă ai avea 100 de animale diferite? Esti sigur ca fiecare animal are atat un nume si o varsta, si asa mai departe? Dacă ați vrea să adăugați alte proprietăți acestor animale? Este lipsită de organizare. Clasele sunt folosite pentru a crea noi structuri de date definite de utilizator care conțin informații arbitrare despre ceva. În cazul unui animal, am putea crea o clasă Animal() pentru a urmări proprietățile despre animal ca numele și vârsta. Este important să rețineți că o clasă oferă doar o structură - este un plan pentru modul în care ar trebui definit ceva, dar nu oferă în realitate nici un conținut real. Clasa Animal() poate specifica faptul că numele și vârsta sunt necesare pentru definirea unui animal. Ar putea ajuta la gândirea unei clase ca o idee pentru cum ar trebui definit ceva. 13

Obiecte Python (instanțe) În timp ce clasa este planul, o instanță este o copie a clasei cu valori reale , literalmente un obiect aparținând unei clase specifice. Nu mai este o idee; este un animal real, ca un câine numit Roger, care are opt ani. Puneți altfel, o clasă este ca un formular sau un chestionar. Definește informațiile necesare. După ce completați formularul, copia dvs. specifică este o instanță a clasei; conține informații reale relevante pentru dvs. Puteți să completați mai multe copii pentru a crea mai multe instanțe diferite, dar fără ca un formular ca ghid, s-ar fi pierdut, fără a ști ce informații sunt necesare. Astfel, înainte de a crea instanțe individuale ale unui obiect, trebuie să specificăm mai întâi ce este necesar definind o clasă.

Cum se definește o clasă în Python Definirea unei clase în Python:

class caine: pass Începeți cu class, cuvântul cheie pentru a indica faptul că creați o clasă, apoi adăugați numele clasei (utilizând notația CamelCase , începând cu o literă de marcă .) De asemenea, am folosit cuvântul cheie Python pass aici. Acest lucru este foarte adesea folosit ca un titular de loc în cazul în care codul va merge în cele din urmă. Aceasta ne permite să executăm acest cod fără să aruncăm o eroare. 14

Notă: Codul de mai sus este corect pentru Python 3. Pe Python 2.x

("Python

vechi"),

veți

folosi

o

definiție

de

clasă

puțin

diferită:

# Python 2.x Clasa Definiție: clasă

Câine ( obiect ):

pass

(obiect)Partea din paranteze specifică clasa părinte pe care o moștenește (mai multe despre acest lucru mai jos). În Python 3 acest lucru nu mai este necesar, deoarece este implicit.

Atribuiri de instanță Toate clasele creează obiecte și toate obiectele conțin caracteristici numite atribute (denumite

în

continuare

proprietăți

în

paragraful

de

deschidere). Utilizați __init__()metoda pentru a inițializa atributele inițiale ale unui obiect prin acordarea valorii lor implicite (sau a stării). Această metodă trebuie să aibă cel puțin un argument, precum și variabila self, care se referă la obiectul însuși (de exemplu, câine).

class caine: def __init__ (self, nume, varsta): self.nume = nume self.varsta = varsta 15

În cazul clasei caine(), fiecare câine are un nume și o anumită vârstă, ceea ce este evident important de știut atunci când începeți să creați câini. Amintiți-vă: clasa este doar pentru definirea câinelui, care nu creează de fapt cazuri de câini individuali cu nume și vârste specifice; vom ajunge la asta în scurt timp. În mod similar, variabila self este, de asemenea, o instanță a clasei. Deoarece exemplele unei clase au valori diferite, am putea spune caine.nume = nume mai degrabă decât self.nume = nume. Dar, deoarece nu toți câinii au același nume, trebuie să putem atribui diferite valori instanțelor diferite. Prin urmare, este nevoie de variabila self specială, care va ajuta la urmărirea instanțelor individuale ale fiecărei clase. NOTĂ : Nu veți mai fi nevoit să apelați metoda __init__(); acesta se apeleaza automat atunci când creați o nouă instanță "caine".

Atribute ale clasei În timp ce atributele instanțelor sunt specifice fiecărui obiect, atributele de clasă sunt aceleași pentru toate instanțele - care în acest caz sunt toți câinii.

class caine:

#

clasa atribut specie = "mamifer"

#

instanta

16

def __init__ (self, nume, varsta): self.nume = nume self.varsta = varsta

Deci, în timp ce fiecare câine are un nume unic și vârstă, fiecare câine va fi un mamifer. Să creăm niște câini ...

Obiecte instante Instantiere este un termen fantezist pentru crearea unei instanțe noi, unice a unei clase. De exemplu:

class caine: pass

# instantiere

caine() caine()

a = caine() b = caine()

if a == b: print("True") else: print("False")

17

Am început să definim o nouă clasa caine(), apoi am creat doi câini noi, fiecare atribuit unor obiecte diferite. Deci, pentru a crea o instanță a unei clase, folosiți numele clasei, urmat de paranteze. Apoi, pentru a demonstra că fiecare instanță este de fapt diferită, am instanțiat încă doi câini, atribuindu-le fiecărei variabile, apoi testat dacă aceste variabile sunt egale. De ce tip credeți că este instanța de clasă?

class caine: pass a = caine() print(type(a))

out:

Să examinăm un exemplu puțin mai complex ...

class caine: specie = 'mamifer'

def __init__ (self, nume, varsta): self.nume = nume self.varsta = varsta

rex = caine("Rex", 2) max = caine("Max", 3)

18

print("Cainele cu numele: " + max.nume + " are varsta de " + format(max.varsta) + " ani.") print("Cainele cu numele: " + rex.nume + " are varsta de " + format(max.varsta) + " ani.") if max.specie == "mamifer": print("{0} este un {1}" .format(max.nume, max.specie))

NOTĂ : Observați cum folosim notația punctului pentru a accesa atributele din fiecare obiect.

Dupa ce ai dat run ar trebui sa vezi: Cainele cu numele: Max are varsta de 3 ani. Cainele cu numele: Rex are varsta de 3 ani. Max este un mamifer

Ce se întâmplă? Am creat o nouă instanță a clasei caine() și l-am atribuit variabilei rex. Apoi i-am dat două argumente "Rex" și 2, care reprezintă numele și vârsta câinelui respectiv. Aceste atribute sunt transmise metodei __init__, care se numește oricând creați o instanță nouă, atașând numele și vârsta la obiect. S-ar putea să te întrebi de ce nu trebuia să trecem la self argument.

19

Aceasta este magia Python; când creați o nouă instanță a clasei, Python determină automat ceea ce este self (un câine în acest caz) și îl transmite __init__ metodei.

Metode de instanță Metodele de instanță sunt definite în interiorul unei clase și sunt utilizate pentru a obține conținutul unei instanțe. Ele pot fi, de asemenea, folosite pentru a efectua operațiuni cu atributele obiectelor noastre. Ca și metoda __init__, primul argument este întotdeauna self:

class caine: specie = 'mamifer' def __init__ (self, nume, varsta): self.nume = nume self.varsta = varsta def descriere (self): return "{0} are varsta de {1} ani si este {2}" .format(self.nume, self.varsta, self.specie)

def sunete (self, sunet): return self.nume + " scoate urmatorul sunet: " + sunet

rex = caine("Rex", 2)

max = caine("Max", 3) print(rex.descriere()) print("Cainele cu numele: " + rex.nume + " are varsta de " + format(max.varsta) + " ani.") print(max.sunete("hamHam"))

20

if max.specie == "mamifer": print("{0} este un {1}" .format(max.nume, max.specie))

Rulați acest exemplu si veti avea ca rezultat: Rex are varsta de 2 ani si este mamifer Cainele cu numele: Rex are varsta de 3 ani. Max scoate urmatorul sunet: hamHam Max este un mamifer

În cea

de-a doua metodă, sunete(),

definim comportamentul. Ce alte

comportamente ați putea atribui unui câine? Poti sa implementezi mai multe exemple din aceasta categorie.

Modificarea atributelor Puteți modifica valoarea atributelor pe baza unor comportamente:

class mesaj: def __init__(self): self.mesaj = False print(self.mesaj)

def trimitere (self): self.mesaj = True print(self.mesaj) return "mesaj trimis"

21

mesajul = mesaj() print(mesajul.trimitere())

Aici am adăugat o metodă de trimitere a unui mesaj, la care se actualizează variabila mesaj ca fiind True. Dupa ce am dat run am obtinut: False True Mesaj trimis

Python moștenirea simpla Moștenirea este procesul prin care o clasă preia atributele și metodele alteia. Clasele nou formate sunt numite clasa copil, iar clasele la care sunt derivate clasele copil sunt denumite clase părinte . Este important să rețineți că clasele de copii suprascriu sau extind funcționalitatea (de exemplu, atributele și comportamentele) ale clasei părinților. Cu alte cuvinte, clasele copil moștenesc toate atributele și comportamentele părintelui, dar pot, de asemenea, să specifice comportamentul diferit de urmat. Cel mai de bază tip de clasă este un obiect, care, în general, toate celelalte clase moștenesc ca părinte.

22

Când definiți o nouă clasă, Python 3 se folosește implicit obiect

ca clasă

parentală. Deci următoarele două definiții sunt echivalente:

clasă

caine ( obiect ):

treci

# În Python 3, este același lucru cu:

clasa

caine: treci

Notă: în Python 2.x există o distincție între clasele de stil nou și vechi . Nu voi intra în detaliu aici, dar în general veți dori să specificați objectca clasă părinte pentru a vă asigura că definiți o clasă de stil nou dacă scrieți codul Python 2 OOP.

Exemplu Să presupunem că suntem la un parc de câini. Există mai multe obiecte de câine care se angajează în comportamentele câinilor, fiecare cu atribute diferite. În mod obișnuit, câinii alergă, în timp ce unii se întind și alții doar urmăresc alți câini. În plus, fiecare câine a fost numit de către proprietarul său și fiecare caine are o vârsta. Care este un alt mod de a diferenția un câine de altul? Ce zici de rasa câinelui:

class caine: def __init__ (self, nume, rasa): self.nume = nume self.rasa = rasa

23

print(" {0} este de rasa {1}" .format(self.nume, self.rasa))

max = caine("Max", "ciobanesc") rex = caine("Rex", "caine-lup")

Dupa rulare: Max este de rasa ciobanesc Rex este de rasa caine-lup Fiecare rasă de câine are comportamente ușor diferit. Pentru a ține cont de acestea, să creăm clase separate pentru fiecare rasă. Acestea sunt clase părinte ale clasei caine, clasa părinte.

Extinderea funcționalității unei clase de părinte

# clasa parinte class caine:

specie = 'mamifer'

#

metoda clasa parinte def __init__ (self, nume, rasa): self.nume = nume self.rasa = rasa

#

metoda clasa parinte

24

def descriere (self): print("{0} este de rasa {1}" .format(self.nume, self.rasa))

#

metoda clasa parinte def vorbeste (self, sunet): print(self.nume + " scoate urmatorul sunet: " + sunet)

# clasa copil class ciobanesc(caine): #

metoda clasa copil def alearga (self, viteza): print("{0} alearga cu viteza {1}" .format(self.nume, self.viteza))

# clasa copil class lup (caine):

#

metoda clasa copil def greutate (self, kg): self.kg = kg print("{0} cantareste {1}" .format(self.nume, self.kg))

max = caine("Max", "ciobanesc") max.descriere() max.vorbeste("hahaham") print()

rex = lup("Rex", "caine-lup") rex.vorbeste("hamham")

25

rex.greutate('12')

Citiți comentariile cu voce tare pe măsură ce lucrați prin acest program pentru a vă ajuta să înțelegeți ce se întâmplă, apoi, înainte de a rula programul, vedeți dacă puteți anticipa rezultatul așteptat. Dupa rulare ar trebui sa afiseze: Max este de rasa ciobanesc Max scoate urmatorul sunet: hahaham

Rex scoate urmatorul sunet: hamham Rex cantareste 12 Dupa cum se observa clasa lup care mosteneste clasa parinte: caine, are o alta metoda metoda si anume metoda greutate. Clasa copil se poate folosi atat de metodele din clasa parinte cat si de metodele pe care le are in clasa ei implementate.

Clasa părinte / copil Funcția isinstance() este utilizată pentru a determina dacă o instanță este, de asemenea , o instanță a unei clase părinte.

# clasa parinte

26

class caine:

specie = 'mamifer'

#

metoda clasa parinte def __init__ (self, nume, rasa): self.nume = nume self.rasa = rasa

#

metoda clasa parinte def descriere (self): print("{0} este de rasa {1}" .format(self.nume, self.rasa))

#

metoda clasa parinte def vorbeste (self, sunet): print(self.nume + " scoate urmatorul sunet: " + sunet)

# clasa copil class ciobanesc(caine):

#

metoda clasa copil def alearga (self, viteza): self.viteza = viteza print("{0} alearga cu viteza {1}" .format(self.nume,

self.viteza))

27

# clasa copil class lup (caine):

#

metoda clasa copil def greutate (self, kg): self.kg = kg print("{0} cantareste {1}" .format(self.nume, self.kg))

max = caine("Max", "ciobanesc") max.descriere() max.vorbeste("hahaham") print()

rex = lup("Rex", "caine-lup") rex.vorbeste("hamham") rex.greutate('12')

campion = ciobanesc("Campion", "dalmatian") campion.alearga('10')

# campion este de tipul ciobanesc print(isinstance(campion, ciobanesc))

# rex este de tipul lup, iar caine este clasa

28

print(isinstance(caine, rex))

Output: Campion alearga cu viteza 10 True Traceback (most recent call last): File "E:\Eclipse\ForHomeWork\src\test2.py", line 49, in print(isinstance(caine, rex)) TypeError: isinstance() arg 2 must be a type or tuple of types

Are sens? Caine este clasa parinte, iar rex este o instanta a clasei lup, clasa lup fiind clasa copil a clasei caine. E norma sa nu functioneze si sa afiseze o eroare, deoarece rex nici macar nu este o clasa, iar functia isinstance asteapta ca unul dintre argumente sa fie clasa, sau tuplu sau un tip.

Anulează funcționalitatea unei clase de părinte Amintiți-vă că clasele copil pot suprascrie atributele și comportamentele de la clasa parentală. De exemplu:

29

class caine:

specie = 'mamifer'

def __init__ (self, nume): self.nume = nume #

return "{0} este un caine!" .format(self.nume)

def descriere (self): return "{0} este un {1}" .format(self.nume, self.specie)

class lup(caine):

def descriere (self): return "{0} este un {1}" .format(self.nume, self.specie)

class ciobanesc(caine):

specie = 'oviparitate'

def descriereCiob (self): return "{0} este un {1}" .format(self.nume, self.specie)

rex = caine('Rex') print(rex.descriere())

gonzales = lup('Gonzales') print(gonzales.descriere())

campion = ciobanesc('Campion')

30

print(campion.descriereCiob())

Afisare:

Rex este un mamifer Gonzales este un mamifer Campion este un oviparitate

Clasa

lup()

moștenește specie

de la clasa părinte, în timp ce Clasa

ciobanesc() atribuie specie = ’oviparitate’.

Mostenirea Multipla Dacă în tuplul de moștenire este listată mai mult de o clasă, acest caz este de moştenire multiplă. În cele mai simple cazuri, vă puteți gândi la căutarea atributelor moștenite de la o clasă parinte de la stânga la dreapta, fără a căuta de două ori în aceeași clasă în cazul în care există o suprapunere în ierarhie. Astfel, dacă un atribut nu este găsit, acesta este căutat în prima clasa, apoi (recursiv) în urmatoarea clasa și așa mai departe.

class A: def afiseaza(self): print("Am gasit metoda!")

31

class B: pass

class C(B, A): def citeste(self, nume): self.nume = nume print("{0} este cu noi.".format(self.nume))

obiect = C() obiect.citeste('Mihai') obiect.afiseaza()

Output: Mihai este cu noi. Am gasit metoda!

Constructori Constructorii sunt utilizați în general pentru a instanția un obiect. Sarcina constructorilor este de a inițializa (atribuie valori) membrilor de date din clasă atunci când este creat un obiect de clasă. În Python, metoda __init __ () este numită constructor și este apelat întotdeauna când este creat un obiect. Definitie: La instantierea unui obiect se apeleaza constructorul. Dar acesta are nevoie ca membrii sa fie functionali => constructorii membrilor se apeleaza inaintea constructorului clasei. 32

Sintaxa:

def __init __ (self): # corpul constructorului

Tipuri de constructori: o constructor implicit: Constructorul implicit este un constructor simplu care nu acceptă niciun argument. Definiția lui are doar un singur argument, care este o referință la instanța care este construită. o constructor parametrizat: constructorul cu parametri este cunoscut ca constructor parametrizat. Constructorul parametrizat ia primul argument ca referință la instanța care este construită, cunoscută ca self, iar restul argumentelor sunt furnizate de programator.

class A: def __init__(self): print("Constructor A")

class B: def __init__(self): print("Constructor B")

a = A()

33

b = B()

Output: Constructor A Constructor B

Destructori Distructorii sunt numiți atunci când un obiect se doreste a fi distrus. În Python, destructorii nu sunt necesari la fel de mult ca în C ++, deoarece Python are un colector

de

gunoi

care

asigura

automat

gestionarea

memoriei.

Metoda __ del __ () este o metodă cunoscută ca metodă în Python. Se apeleaza atunci când toate trimiterile la obiect au fost șterse, adică atunci când un obiect este colectat de gunoi.

Notă: Distructorul a fost chemat după terminarea programului sau când toate referințele la obiect sunt șterse, adică când numărul de referință devine zero, nu când obiectul a ieșit din domeniul de aplicare.

class A: def __init__(self):

34

print("Constructorul A s-a apelat!\n")

def __del__ (self): print("Destructorul A s-a apelat!")

def faCeva (self): print("Aceasta este o metoda de demonstratie pentru clasa A:") a = 2 b = 2 c = a/b print("Rezultat: {0} \n" .format(c)) class B: def __init__(self): print("Constructorul B s-a apelat!\n")

def __del__(self): print("Destructorul B s-a apelat!") def faCeva (self): print("Aceasta este o metoda de demonstratie pentru clasa B:") a = 5 b = 2 c = a/b print("Rezultat: {0} \n" .format(c))

b = B() b.faCeva() a = A() a.faCeva()

Ce credeti ca s-a obtinut? Output: 35

Constructorul B s-a apelat! Aceasta este o metoda de demonstratie pentru clasa B: Rezultat: 2.5 Constructorul A s-a apelat! Aceasta este o metoda de demonstratie pentru clasa A: Rezultat: 1.0 Destructorul B s-a apelat! Destructorul A s-a apelat!

Acest modul oferă o interfață pentru colectorul opțional de gunoi. Oferă posibilitatea de a dezactiva colectorul, de a regla frecvența de colectare și de a seta opțiunile de depanare. Oferă, de asemenea, acces la obiecte nedovedite pe care colectorul le-a găsit, dar nu le poate elibera. Deoarece colectorul suplimentează numărarea de referință deja utilizată în Python, puteți dezactiva colectorul dacă sunteți sigur că programul dvs. nu creează cicluri de referință. Colectarea automată poate fi dezactivată prin apelare gc.disable(). Pentru a depana un apel de scurgere program gc.set_debug(gc.DEBUG_LEAK) . Observați că acest lucru includegc.DEBUG_SAVEALL, provocând salvarea obiectelor colectate în gc.garbage pentru inspecție. Un exemplu pentru momentul in care „colectorul de gunoaie” isi intra in rol.

36

class A: def __init__(self): B.__init__(self) class B(A): def __init__(self): A.__init__(self) def aduna(self, x, y, z=0): return x+y+z ob = B() print(ob.aduna(1, 2)) print(ob.aduna(1, 2, 3))

Output: … … … B.__init__(self) File "E:\Eclipse\ForHomeWork\src\test2.py", line 7, in __init__ A.__init__(self) File "E:\Eclipse\ForHomeWork\src\test2.py", line 3, in __init__ B.__init__(self) RecursionError: maximum recursion depth exceeded

In acest caz, gc, a oprit rularea programului in mod automat.

Polimorfismul În programare, polimorfismul înseamnă același nume de funcție (dar semnături diferite) fiind utilizări pentru diferite tipuri. Exemplu de functii polimorfice predefinite:

37

print(len("numele")) print(len([10, 20, 40]))

Output: 6 3

Exemple de functii polimorfice definite: def aduna(x, y, z=0): return x+y+z

print(aduna(1, 2)) print(aduna(1, 2, 3))

Output: 6 3

Exemple de polimorfism in cazul claselor mostenite si a metodelor: class A: def __init__(self): print("Clasa A")

38

def aduna(self, x, y, z=0): return x+y+z class B(A): def __init__(self): print("Clasa B") def aduna(self, x, y, z=0): return x+y+z ob = B() print(ob.aduna(1, 2)) print(ob.aduna(1, 2, 3)) ob1 = A() print(ob1.aduna(1, 2)) print(ob1.aduna(1, 2, 3))

în Python, polimorfismul ne permite să definim metode în clasa copil care au același nume ca și metodele din clasa parinte. În moștenire, clasa copil moștenește metodele din clasa părinte. Cu toate acestea, este posibil să modificați o metodă într-o clasă copil pe care a moștenit-o de la clasa parinte. Acest lucru este deosebit de util în cazurile în care metoda moștenită de la clasa părinte nu se potrivește perfect clasei copil.

Incapsularea Încapsularea este un conctept cheie în programarea orientată pe obiecte. În Python, pentru a ascunde membrii unei clase, se folosește următoarea convenție:

_member

- prefixarea cu un underscore, pentru membri protected, permite modificarea

atributului doar în interiorul clasei sau de către un moștenitor; 39

__member

- prefixarea cu două underscore-uri, pentru membri private, interzice accesul

la atribut din afara clasei. class Elev:

__clasa = 11

def __init__(self, nume, medie): self.__nume = nume self.__medie = medie

def afisare (self): print("{0} are media {1}" .format(self.__nume, self.__medie))

def set_nume(self, nume): self.__nume = nume; print("Ati setat numele: {0}".format(self.__nume))

def get_nume(self): print("Numele este: {0}".format(self.__nume))

ob = Elev("Mihai", '9.80')

ob.afisare() ob.set_nume("Ion") ob.get_nume() ob.afisare() print(ob.__clasa)

Output: 40

Mihai are media 9.80 Ati setat numele: Ion Numele este: Ion Ion are media 9.80 Traceback (most recent call last): File "E:\Eclipse\ForHomeWork\src\test2.py", line 25, in print(ob.__clasa) AttributeError: 'Elev' object has no attribute '__clasa' Python protejează membrii privați prefixându-le numele cu numele clasei din care fac parte. Așadar, încapsularea este o convenție, încurajând programatorii să fie responsabili, și nu restricționând complet accesul. În exemplul de mai sus, se poate accesa membrul privat astfel: ob._Elev__clasa

Structura dinamică a claselor În Python, membrii unei clase se pot schimba în timpul rulării (nu doar valoarea acestora, ca în C sau Java). In continuare va voi arata cateva exemple, printre care si adaugarea clasei A deja definite un atribut y. Orice nouă instanță a clasei A va avea acest nou atribut. class A:

ab = 0

41

def setx (self, x): self.x = x

def printx (self): print("x este {0}".format(self.x))

f = A()

# se poate adauga f.setx(2) print(f.x)

A.y = 10 print(f.y)

# se poate sterge del f.x print(f.x)

Exceptii O exceptie este o eroare care apare atunci cand un program ruleaza si care are drept consecinta oprirea lui brutala. Pentru manuirea exceptilor se foloseste blocul de declaratii try/except. class A:

ab = 0

42

def setx (self, x): self.x = x def printx (self): print("x este {0}".format(self.x))

f = A()

# se poate adauga f.setx(2) print(f.x)

A.y = 10 print(f.y)

# se poate sterge del f.x try: print(f.x) except: print("Eroare")

Output:

2 10 Eroare\

Erori care apar in Python: (tabel preluat din cartea „Cum sa programezi in Python, Mircea Prodan, 2014) Exceptii AssertionError AttributeError EOFError FloatingPointError IOError IndexError KeyError OSError OverflowError

Descriere Apare atunci cand declaratia esueaza Atributul nu este gasit in obiect Cand se incearca citirea dincolo de sfarsitul unui fisier Apare cand operatia cu un numar in virgula mobila esueaza Cand o operatie I/O esueaza Cand se foloseste un index aflat in afara gamei (range) Cand o cheie nu este gasita Cand invocarea unui sistem de operare esueaza Cand o valoarea este prea mare ca sa poata fi reprezentata

43

TypeError ValueError ZeroDivisionError

Cand un argument de un tip nepotrivit este furnizat Cand valoarea unui argument nu este potrivita Cand un numar se imparte la zero ori cand al doilea argument intr‑o operatie modulo este zero

This Atat self cât și this sunt folosite pentru același lucru. Ele sunt folosite pentru a accesa variabila asociată cu instanța curentă. Numai diferența este că trebuie să includeți self , explicit, ca prim parametru o metodă de instanță în Python, în timp ce acest lucru nu este cazul cu Java. Mai mult, numele self poate fi orice. Nu este un cuvânt cheie, puteți chiar să o schimbați this și va funcționa bine. Dar oamenilor le place să folosească self, așa ca a devenit convenție.

class Persoana:

def __init__(self, nume, varsta): self.nume = nume self.varsta = varsta print("{0} are varsta de {1} ani" .format(self.nume, self.varsta))

ion = Persoana('Ion', '54')

Output:

Ion are varsta de 54 ani

44

Bibliografie: Curs OP - Conferentiar universitar dr. Socaciu Tiberiu „Cum sa programezi in Python” - Mircea Prodan, 2014 https://docs.python.org/3/library/gc.html http://purepython.eaudeweb.ro/wiki/Cursuri/Programare-orientat%C4%83-pe-obiecte.html https://github.com/eaudeweb/purepython/wiki/Programare-orientat%C4%83-pe-obiecte https://stackoverflow.com https://realpython.com http://www.e-learn.ro https://opentechschool.github.io https://ocw.cs.pub.ro

45