Sunteți pe pagina 1din 88

Tutorial Python

Versiune 2.2

Guido van Rossum Fred L. Drake, Jr., editor

9. Decembrie 2001

PythonLabs Email:
python-docs@python.org

Copyright c 2001 Python Software Foundation. All rights reserved. Copyright c 2000 BeOpen.com. All rights reserved. Copyright c 1995-2000 Corporation for National Research Initiatives. All rights reserved. Copyright c 1991-1995 Stichting Mathematisch Centrum. All rights reserved. See the end of this document for complete license and permissions information.

Abstract Python este un limbaj de programare puternic si uor de nvat. Are structuri de date de nivel nalt, eciente si o s at simpl dar ecient abordare a program rii orientate pe obiect. a a a Sintaxa elegant si natura sa interpretat , fac din Python un limbaj ideal pentru elaborarea de script-uri si dezvoltarea a a rapid de aplicaii n multe domenii, pe majoritatea platformelor. a t Interpretorul Python si libr ria standard sunt oferite sub form de surse sau compilate pentru majoritatea platformelor a a existente, pe site-ul Python, http://www.python.org/, si pot distribuite gratuit. Pe acelai site putei g si s t a distribuii Python si module scrise de ali programatori, precum si documentaie adiional . t t t t a Interpretorul Python este uor de extins prin ad ugarea de noi funcii si tipuri de date implementate n C sau C++ (sau s a t alte limbaje apelabile din C). Python poate folosit si drept limbaj de extensie pentru aplicaii. t Acest material informeaz cititorul despre conceptele de baz si capabilitile sistemului si limbajului Python. Ar a a at de preferat s avei la ndemn un interpretor Python pentru a experimenta, dar toate exemplele cuprinse n acest a t a material pot nelese f r a imperativ prezena interpretorului. t aa a t Pentru o descriere a obiectelor si modulelor standard, consultai documentul Python Library Reference. Documentul t Python Reference Manual d o deniie mai exact a limbajului. Dac dorii s extindei sau s implementai limbajul a t a a t a t a t Python ntr-o aplicaie cu ajutorul C++ consultai documentul Extending and Embedding the Python Interpreter si t t Python/C API Reference. Exist si c ri care acoper limbajul Python n toat complexitatea sa. a at a a Acest tutorial nu ncearc s acopere toate facilitile Python-ului, sau m car cele mai folosite dintre ele. n schimb, a a at a v prezint cele mai interesante si importante faciliti, si v va da o idee despre modul de funcionare al limbajului. a a at a t Dup ce vei citi acest tutorial, vei putea citi si scrie module sau programe Python, si vei preg tii s vai mai a t t t a t a at t multe despre diferitele libr rii incluse n distribuia Python, descrise n documentul Python Library Reference. a t

CUPRINS

1 2

De ce Python? 1.1 n continuare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Utilizarea interpretorului Python 2.1 Invocarea interpretorului . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Interpretorul si mediul n care ruleaz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a O introducere scurt n Python a 3.1 Utilizarea Python-ului drept calculator de birou . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Primii pai n programare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . s Structuri de control 4.1 Instruciuni if . . . . . . . . . . . . . . . . . . . . . . . . . . t 4.2 Instruciuni for . . . . . . . . . . . . . . . . . . . . . . . . . t 4.3 Funcia range() . . . . . . . . . . . . . . . . . . . . . . . . t 4.4 Instruciuni break si continue, si clauze else pentru bucle t 4.5 Instruciuni pass . . . . . . . . . . . . . . . . . . . . . . . . t 4.6 Funcii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t 4.7 Mai multe despre funcii . . . . . . . . . . . . . . . . . . . . . t Strucuri de date 5.1 Mai multe despre liste . . 5.2 Instruciunea del . . . . t 5.3 Perechi si secvene . . . . t 5.4 Dicionare . . . . . . . . t 5.5 Mai multe despre condiii t 5.6 Compararea secvenelor . t Module 6.1 Mai multe despre module 6.2 Module standard . . . . . 6.3 Funcia dir() . . . . . t 6.4 Pachete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1 2 3 3 4 7 7 17 19 19 19 20 21 21 22 23 29 29 33 34 35 35 36 37 38 39 40 41 45 45 47 51 51

Intr ri si ieiri a s 7.1 Formatarea mai elegant a datelor la ieire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a s 7.2 Fiiere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . s Erori si excepii t 8.1 Erori de sintax a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8.2 8.3 8.4 8.5 8.6 9

Excepii . . . . . . . . . . . . t Tratarea excepiilor . . . . . . t Generarea excepiilor . . . . . t Excepii denite de utilizator . t Denirea aciunilor de curare t at

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

51 52 54 55 56 59 59 60 61 64 65 66 67 69

Clase 9.1 Cteva cuvinte despre terminologie . . . . . . . . . . . . . . . . . . . . . . . . 9.2 Domenii de vizibilitate (Scopes) si domenii de deniie a numelor(Name Spaces) t 9.3 O prim privire asupra claselor . . . . . . . . . . . . . . . . . . . . . . . . . . a 9.4 Alte observaii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t 9.5 Motenirea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . s 9.6 Variabile private . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.7 Altfel de clase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . .

10 Continuarea? A Editarea n linie de comand si repetarea comenzilor anterioare a A.1 Editarea n linie de comand . . . . . . . . . . . . . . . . . a A.2 Repetarea comenzilor anterioare(History) . . . . . . . . . . A.3 Redenirea tastelor funcionale . . . . . . . . . . . . . . . . t A.4 Comentarii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

71 71 71 72 73 75 77 79 79 80

B Aritmetica n virgul otant : rezultate si limit ri a a a B.1 Erori de reprezentare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C Istoria si licena t C.1 Istoricul produsului Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.2 Terms and conditions for accessing or otherwise using Python . . . . . . . . . . . . . . . . . . . . .

ii

CAPITOL

UNU

De ce Python?
Dac ai construit vreodat un shell complex, probabil cunoatei senzaia: vrei s ad ugai nc o facilitate, dar este a t a s t t t a a t a deja att de lent, att de mare, att de complicat; sau ad ugarea facilitii implic un apel de funcie de sistem, sau alt a at a t a funcie care nu este accesibil dec t din C. De obicei problema pe care o avei de rezolvat nu este sucient de serioas t a a t a astfel nct s merite s rescriei shell-ul n C; poate c rezolvarea problemei necesit folosirea sir-urilor de lungime a a t a a variabil , sau a listelor sortate de nume de iere, lucruri accesibile ntr-un shell, dar care necesit mult munc pentru a s a a a a implementate n C; sau poate c nu suntei sucient de familiarizat cu limbajul C. a t S consider m o alt situaie: presupunem c trebuie s lucrai cu anumite biblioteci C, si ciclul obinuit de scrierea a a t a a t s compilare-testare-recompilare este prea lent. Vrei s dezvoltai mult mai rapid software. E posibil s scris un t a t a program care poate folosi un limbaj de extensie, si nu vrei s dezvoltai un alt limbaj pentru asta, s scriei si s t a t a t a vericai de erori un interpretor pentru acest limbaj, pentru ca apoi s -l ad ugai la aplicaia dumneavoastr . t a a t t a n aceste cazuri Python este limbajul de care avei nevoie. Este simplu de folosit, dar este un limbaj de programare t adev rat, oferind posibilitatea unei mai bune structur ri, si un suport mai bun pentru programe mari dect ofer un a a a shell. Pe de alt parte dispune de o mult mai bun vericare a erorilor dect C-ul, si ind un limbaj de nivel foarte a a nalt, dispune de tipuri de date de nivel nalt cum ar tablouri sau dicionare foarte exibile, a c ror implementare n t a C ar lua programatorului zile. Datorit caracterului general al tipurilor de date Python poate aplicat ntr-o arie mult a mai larg de probleme dect AWK sau PERL. Cu toate astea, multe lucruri se realizeaz la fel de uor n Python ca si a a s n aceste limbaje. Python permite divizarea programelor dumneavoastr n module care pot folosite apoi n alte programe Python. a Dispune de o colecie vast de module standard de la care putei porni n construirea programului dumneavoastr , sau t a t a pentru a nva programarea n Python. at Exist de asemenea module ncorporate care ofer faciliti pentru sistemul de intr ri ieiri (I/O), apeluri de sistem, a a at a s sockets, si chiar interfee pentru sisteme de interfaare grac utilizator (GUI) precum TK. t t a Python este un limbaj interpretat, care v poate accelera munca n timpul procesului de dezvoltare, ne mai ind nevoit a s compilai codul de ecare dat . Interpretorul poate folosit interactiv, ceea ce v permite s testai foarte uor a t a a a t s anumite faciliti ale limbajului, s scriei imediat programe dispensabile, sau s testai anumite funcii nainte de a le at a t a t t folosi n programul dumneavoastr . Este foarte folositor si drept, calculator de birou. a Python permite scrierea unor programe foarte compacte si uor de citit. Programele scrise n Python sunt mult mai s mici decat echivalentele n C sau C++ pentru c : a tipurile de date de nivel nalt v permit s realizai operaii complexe ntr-o singur instruciune; a a t t a t gruparea instruciunilor este dat de paragrafare n loc de blocuri begin/end sau de acolade; t a nu este necesar declararea variabilelor. a Python este extensibil: dac avei cunotine de C putei foarte uor sa ad ugai o nou funcie sau un modul, e pentru a t s t t s a t a t a efectua operaii la vitez maxim , e pentru a lega programe Python la biblioteci disponibile numai n form binar t a a a a (biblioteci grace). Putei de exemplu s ad ugai interpretorul Python ntr-o aplicaie C si s l folosii ca un limbaj t a a t t a t de comand sau de extensie pentru acea aplicaie. a t 1

Numele limbajului provine de la emisiunea BBC Monthy Pythons Flying Circus (Circul zbur tor al sarpelui Monty) a si nu are nici o leg tur cu disgraioasele reptile. Referine la Monty Python n documentaia ce urmeaz nu numai c a a t t t a a sunt permise, sunt chiar ncurajate!

1.1

n continuare

Acum c avei o idee despre Python, poate dorii s l examinai mai n detaliu. Din moment ce, cea mai bun metod a t t a t a a de a nvaa un limbaj de programare este utilizarea acestuia, suntei si dumneavoastr invitai s o facei. t t a t a t n urmatorul capitol este explicat utilizarea interpretorului. Informaiile ce urmeaz pot p rea banale, dar sunt esa t a a eniale pentru testarea exemplelor ce vor urma. t Cealalt parte a tutorialului prezint diferite facilitai ale limbajului Python. Aceast prezentare este bogat n exemple, a a t a a ncepnd cu expresii simple, instruciuni, tipuri de date si terminnd cu funcii, module si concepte avansate cum ar t t tratarea excepiilor si clase denite de utilizator. t

Capitol 1. De ce Python?

CAPITOL

DOI

Utilizarea interpretorului Python


2.1 Invocarea interpretorului

Interpretorul Python este deobicei instalat n /usr/local/bin/python pe mainile unde exist aceast cale. n lista cu s a a directoarele de sistem a U NIX introducei calea /usr/local/bin pentru a putea porni interpretorul cu comanda : t
python

Din moment ce directorul n care este instalat interpretorul, poate modicat la instalare, si alte c i sunt posibile. a Vorbii cu administratorul dumneavoastr de sistem nainte de a lua o decizie n privina directorului de instalare. (Ex: t a t /usr/local/python este o alternativ foarte popular ). a a Tastarea unui caracter de sfrit de ier (Control-D pe U NIX, sau Control-Z pe DOS sau Windows) n tims s pul prompt-ului principal determin oprirea execuiei interpretorului cu cod de ieire zero. Dac acest lucru nu a t s a funcioneaz ncercai comenzile: import sys; sys.exit(). t a t Facilitile de editare n linie de comand ale interpretorului nu sunt deloc deosebite. Pe sisteme U NIX, n timpul at a instal rii Python, putei activa opiunea de suport a bibliotecii GNU de editare n linie de comand , care adaug mai a t t a a multe faciliti pentru editare n linie de comand . Pentru a vedea dac aceast opiune este activat , tastai combinaia at a a a t a t t de taste Control-P la primul prompt Python. Dac auzii un sunet, avei activat opiunea despre care vorbeam mai a t t a t sus (consultai Anexa A, pentru o scurt list de combinaii de taste foarte utile). Dac nu se ntampl nimic sau este t a a t a a aat ^P, opiunea de editare a liniei de comand nu este activat , deci nu vei putea dect s stergei (BACKSPACE) s t a a t a t sau s introducei noi caractere n linie. a t Interpretorul funcioneaz aseman tor shell-ului U NIX: Cnd este apelat cu intrarea standard conectat la un dispozitiv t a a a TTY, citete si execut comenzi interactiv. Cnd este apelat cu un parametru reprezentnd un nume de ier, citete si s a s s execut un script (program) din acel ier. a s O a treia modalitate de a porni interpretorul este python -c command[arg] . . . care execut instrucia t unea/instruciunile din comand , analog opiunii -c a shell-ului. Din moment ce o comand poate conine spaii sau t a t a t t alte caractere utilizate de shell (ca separatori de parametrii de exemplu) este bine s introducei comanda/comenzile a t ntre ghilimele. Observai c exist o diferena ntre python file si python <file. n primul caz, datele de intrare ale t a a t programului sunt oferite de ier. Din moment ce acest ier a fost deja citit pan la cap t nainte de nceperea s s a a programului, programul va ntlni sfrit de ier imediat. n al doilea caz (cel mai interesant si folosit) datele de s s intrare sunt oferite de orice ier sau dispozitiv conectat la intrarea standard a interpretorului Python. s Cnd este rulat un script, este cteodat folositor ca dup rularea script-ului s se intre n modul interactiv. Acest lucru a a a se realizeaz foarte simplu folosind un parametru -i nainte de numele ierului n care se a script-ul. Evident c a s a a acest parametru nu va funciona dac script-ul este citit de la intrarea standard. t a

2.1.1

Transmiterea argumentelor

Atunci cnd dup parametrul care reprezint ierul n care se a script-ul, interpretorului i se mai transmit si ali a a s a t parametrii, acesta i va transmite mai departe script-ului prin intermediul variabilei sys.argv, variabil ce conine o a t list (vector) de siruri de caractere. Atunci cnd n loc de numele ierului se transmite _ (adic intrarea standard), a s a sys.argv[0] = _. Cnd este folosit comanda -c, sys.argv[0] = -c. Parametrii de dup -c comand nu a a a sunt considerai parametrii ai interpretorului, ci sunt scrii n sys.argv pentru a folosii de comand . t s t a

2.1.2

Modul interactiv

Cnd comenzile sunt citite de la un TTY, se spune c interpretorul se a n modul interactiv. n acest mod exist a a a dou prompt-uri. Prompt-ul principal (de obicei >>> ) si promptul secundar (de obicei ... ) folosit pentru a continuarea liniilor. Interpretorul aeaz imediat dup pornire un mesaj de ntmpinare ncare se specic versiunea s a a a si autorii Python-ului, urmate de primul prompter :
python Python 1.5.2b2 (#1, Feb 28 1999, 00:02:06) [GCC 2.8.1] on sunos5 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam >>>

Liniile de continuare sunt folosite la introducerea unei construcii multilinie. De exemplu: t


>>> pamantul_este_plat = 1 >>> if pamantul_este_plat: ... print "Ai grija sa nu cazi!" ... Ai grija sa nu cazi!

2.2 Interpretorul si mediul n care ruleaza


2.2.1 Tratarea erorilor

Cand are loc o eroare, interpretorul aeaz un mesaj de eroare si starea stivei n momentul respectiv. n modul s a interactiv revine la prompt-ul principal. Atunci cnd intr rile provin dintr-un ier, interpretorul se oprete cu un cod a s s de eroare diferit de zero dup ce a aat starea stivei.(Excepiile tratate nu sunt erori n acest context). Unele erori a s t sunt inevitabil fatale si cauzeaz terminarea anormal cu cod de ieire diferit de zero (Ex: lipsa de memorie). Toate a a s mesajele de eroare sunt scrise la ieirea pentru erori (standard error stream). Ieirile provenite din execuia comenzilor s s t sunt scrise la ieirea standard. s Dac se apas caracterul de ntrerupere (Control-C, DEL) n primul prompt sau n cel secundar, comanda scris a a a este pierdut revenindu-se la promptul principal. ntreruperea unei comenzi n timpul execuiei creeaz o excepie de a t a t tip Keyboard Interrupt, care poate tratat ntr-o instruciune try. a t

2.2.2

Script-uri Python Executabile

Pe sisteme U NIX,BSD, scripturile Python pot f cute direct executabile, la fel ca scripturile de shell, punnd linia a
#! /usr/bin/env python

Capitol 2. Utilizarea interpretorului Python

(presupunem c interpretorul se a n variabila de sistem PATH a utilizatorului) la nceputul script-ului si apoi transa a formnd ierul n executabil. Caracterele #! trebuie s e neap rat primele dou caractere din ier. s a a a s Observaie: Caracterul # este folosit pentru comentarii n Python. t

2.2.3

Fi ierul de iniializare al modului interactiv s t

Cnd folosii Python n modul interactiv, poate foarte folositor s avei cteva comenzi care s se execute automat de t a t a ecare dat cnd este pornit interpretorul. Putei realiza acest lucru crend o variabil de sistem cu numele PYTHONa t a STARTUP care s conin numele unui ier n care s avei comenzile, care dorii s e executate la pornirea intera t a s a t t a pretorului. Aceast procedur este similar , facilitii .prole de pe sistemele U NIX. Acest ier de iniializare este a a a at s t interpretat numai cnd este pornit interpretorul Python n mod interactiv. Fiierul nu este interpretat nici cnd interpres torul Python are ca intrare un ier, nici cnd sursa explicit a comenzilor este /dev/tty. Acest ier este executat n s a s acelai cadru n care se execut si comenzile interactive. n acest ier pot schimbate chiar si prompt-urile sys.ps1 s a s sau sys.ps2. Dac dorii s executai si alte iere de iniializare, din directorul curent trebuie s ad ugai cteva linii la ierul a t a t s t a a t s principal de iniializare, utiliznd un cod ca acesta if os.path.isfile(.pythonrc.py) : exect file(.pythonrc.py) Dac dorii s folosii acest ier de iniializare, ntr-un program, trebuie s specicai acest lucru explicit n cadrul a t a t s t a t programului astfel:
import os filename = os.environ.get(PYTHONSTARTUP) if filename and os.path.isfile(filename): execfile(filename)

2.2. Interpretorul si mediul n care ruleaza

CAPITOL

TREI

O introducere scurta n Python


n exemplele ce urmeaz , intr rile si ieirile vor deosebite prin prezena sau absena prompt-urilor (principal >>> a a s t t sau secundar ... ). Pentru a testa un exemplu trebuie s scriei linia ce apare imediat dup prompt. Liniile care nu a t a au caracterele >>> sau ... n faa sunt linii de ieire, rezultate n urma comenzilor anterioare, sau a ultimei t s comenzi. Un prompt secundar, f r nimic dup el, nseamn c trebuie s introducei o linie goal . Acest procedeu aa a a a a t a este folosit pentru terminarea unui bloc de instruciuni (de tipul begin...end;{...}). t Multe din exemplele din acest tutorial conin comentarii. n Python comentariile ncep cu un caracter # si se termin t a la sfritul liniei. Un comentariu poate ap rea la sfritul unei linii, dar nu poate ap rea n cadrul unui string. Un s a s a caracter # n cadrul unui string nu reprezint nceputul unui comentariu ci doar un caracter #. Iat cteva exemple: a a
# primul comentariu SPAM = 1

# \c{s}i al doilea comentariu # ... \c{s}i al treilea! STRING = "# Acesta nu este un comentariu."

3.1

Utilizarea Python-ului drept calculator de birou

S ncerc m cteva comenzi simple Python. Pornii interpretorul si ateptai s apar prompt-ul principal >>> .(Nu a a t s t a a ar trebui s dureze prea mult). a

3.1.1

Numere

Interpretorul funcioneaz ca un simplu calculator: putei scrie o expresie, si ca r spuns vei primi rezultatul. Ordinea t a t a t operaiilor si modul de parantezare sunt la fel ca n majoritatea limbajelor (ex: Pascal sau C). t De exemplu:

>>> 4 >>> ... 4 >>> 5 >>> ... ... 2 >>> -3

2+2 # Acesta este un comentariu 2+2 # Un comentariu pe aceia\c{s}i linie de cod (50 - 5 * 6) / 4 # Impartirea numerelor intregi are ca rezultat, de fapt, # partea intreaga a rezultatului impartirii 7 / 3 7 / -3

La fel ca n C, semnul egal (=) este folosit la atribuire. Valoarea atribuit nu constituie o ieire (nu este tip rit pe a s a a ecran):
>>> latime = 20 >>> inaltime = 5*9 >>> latime * inaltime 900

O valoare poate atribuit simultan mai multor variabile: a


>>> >>> 0 >>> 0 >>> 0 x = y = z = 0 x y z # x, y \c{s}i z devin zero

Exist suport complet pentru virgul mobil . Operatorii care au operanzi de tipuri diferite vor converti operandul a a a ntreg n virgul mobil : a a
>>> 3 * 3.75 / 1.5 7.5 >>> 7.0 / 2 3.5

Numerele complexe sunt de asemenea suportate. Numerele imaginare sunt scrise cu suxul j sau J. Numerele complexe cu parte real diferit de zero au forma (real+imagj) sau pot create folosind funcia complex(real, a a t imag):

Capitol 3. O introducere scurta n Python

>>> 1j * 1J (-1+0j) >>> 1j * complex(0,1) (-1+0j) >>> 3+1j*3 (3+3j) >>> (3+1j)*3 (9+3j) >>> (1+2j)/(1+1j) (1.5+0.5j)

Numerele complexe sunt ntotdeauna reprezentate ca dou numere reale n virgul mobil : partea real si cea imagia a a a nar . Pentru a aa partea real sau cea imaginar dintr-un num r complex z folosii z.real respectiv z.imag: a a a a t
>>> a=1.5+0.5j >>> a.real 1.5 >>> a.imag 0.5

Funciile de conversie la numere reale sau ntregi nu funcioneaz pentru numere complexe, neexistnd o metod t t a a matematic de a transforma un num r complex ntr-un numar real. Folosii funcia abs(z) pentru a calcula modulul, a a t t sau z.real pentru a aa partea real : a
>>> a=3.0+4.0j >>> float(a) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: cant convert complex to float; use e.g. abs(z) >>> a.real 3.0 >>> a.imag 4.0 >>> abs(a) # sqrt(a.real**2 + a.imag**2) 5.0 >>>

n modul interactiv ultima valoare aat este atribuit unei variabile _. Dac folosii Python ca un calculator de birou s a a a t este mult mai uor s p strai continuitatea calculelor: s a a t
>>> tax = 12.5 / 100 >>> price = 100.50 >>> price * tax 12.5625 >>> price + _ 113.0625 >>> round(_, 2) 113.06 >>>

Aceast variabil trebuie tratat de utilizator ca avnd numai capacitatea de a citit , nu si scris (READ-ONLY). Nu a a a a a atribuii valori acestei variabile, deoarece acest lucru nseamn c vei creea o variabil nou local care va ascunde t a a t a a a 3.1. Utilizarea Python-ului drept calculator de birou 9

variabila implicit _ si comportamentul s u extraordinar. a a

3.1.2

Siruri de caractere

n afar de numere Python poate manipula si siruri de caractere, care pot(exista) avea mai multe forme. Pot incluse a ntre apostroafe sau ghilimele:
>>> omleta omleta >>> n-a "n-a" >>> "n-a" "n-a" >>> "Da," a spus el. "Da," a spus el. >>> "\"Da,\" a spus el." "Da," a spus el. >>> "Nu," a spus ea. "Nu," a spus ea.

Sirurile de caractere pot exista pe mai multe linii, separarea realizndu-se prin secvena de control \n indicnd t astfel ca linia urm toare este continuarea logic a liniei curente : a a
hello = "Acesta este un \c{s}ir de caractere mai lung,\n\ care se intinde pe mai mai multe linii, exact ca \^{i}n C.\n\ Observati ca spatiile de la inceputul liniei\ au importanta." print hello

De notat c r mne necesar ca semnele de linie nou s e incluse n sir utiliznd \n; linia nou care urmeaz ultimului a a a a a a backslash este eliminat . Acest exemplu va aa urm toarele: a s a
Acesta este un \c{s}ir de caractere mai lung, care se intinde pe mai mai multe linii, exact ca \^{i}n C. Observati ca spatiile de la inceputul liniei au importanta.

Dac construim sirul de caractere ca un sir raw, atunci secvena \n nu se convertete n linie nou , dar backslesh-ul a t s a de la sfritul liniei si caracterul de linie nou din surs sunt incluse n sir ca date. Iat un exemplu : s a a a
hello = r"Acesta este un \c{s}ir de caractere mai lung,\n\ care se intinde pe mai mai multe linii, exact ca \^{i}n C." print hello

va tipari:

10

Capitol 3. O introducere scurta n Python

Acesta este un \c{s}ir de caractere mai lung,\n\ care se intinde pe mai mai multe linii, exact ca \^{i}n C.

Sirurile de caractere pot exista si ntre perechi de cate trei ghilimele sau apostroafe (""" sau ). n acest caz nu avei nevoie de caracterele de control (ex: \n\) pentru a realiza separarea liniilor: t
print """ Usage: thingy [OPTIONS] -h -H hostname """

Display this usage message Hostname to connect to

are urm toarea ieire: a s


Usage: thingy [OPTIONS] -h -H hostname

Display this usage message Hostname to connect to

Interpretorul aeaz rezultatul operaiilor cu siruri de caractere exact n forma specicat de utilizator atunci cnd a s a t a introdus sau denit sirurile respectiv: ntre ghilimele, cu ghilimele sau alte caractere ciudate, pentru a aa valoarea s exact a sirului. Instruciunea print despre care v vom vorbi mai ncolo poate folosit pentru a aa siruri f r a t a a s aa ghilimele si caractere de control. Sirurile de caractere pot concatenate:
>>> word = Help + A >>> word HelpA >>> < + word*5 + > <HelpAHelpAHelpAHelpAHelpA>

Dou siruri de caractere scrise unul lng altul sunt concatenate. Prima linie din exemplul de mai sus poate rea a scris astfel: word = HelpA. Acest lucru nu merge dect pentru siruri explicite de caractere, nu pentru orice a expresie care are ca operanzi siruri:
>>> import string >>> str ing string >>> string.strip(str) + ing string >>> string.strip(str) ing File "<stdin>", line 1, in ? string.strip(str) ing ^ SyntaxError: invalid syntax

# # #

<<<-

This is ok This is ok This is invalid

Sirurile de caractere sunt tratate ca vectori, la fel ca nC: primul caracter al unui sir are indicele 0. Nu exist un tip de a date separat pentru caracter. Un singur caracter este reprezentat ca un sir de lungime unu. Se pot specica de asemenea subiruri ale unui sir folosind doi indici, separai prin :. Primul indice reprezint poziia de nceput a subirului, iar s t a t s

3.1. Utilizarea Python-ului drept calculator de birou

11

cel de-al doilea indice, evident indicele n sirul principal la care se termin subirul: a s
>>> word[4] A >>> word[0:2] He >>> word[2:4] lp

Dac al doilea indice nu este specicat, se consider c subirul se termin la sfritul sirului. a a a s a s Spre deosebire de C, n Python sirurile nu pot modicate. Atribuirea unei valori unui anumit caracter, sau unui subir s dintr-un sir mai mare, va genera o eroare:
>>> word[0] = x Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: object doesnt support item assignment >>> word[:1] = Splat Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: object doesnt support slice assignment

n orice caz, creearea unui sir nou cu un coninut combinat este sucient de simpl si ecient : t a a
>>> x + word[1:] xelpA >>> Splat + word[4] SplatA

Omiterea primului sau celui de-al doilea indice n specicarea parametrilor unui subir, are ca efect nlocuirea primus lui indice cu zero, respectiv cu lungimea sirului din care se ncearc extragerea subirului, dac se omite al doilea a s a parametru.
>>> word[:2] He >>> word[2:] lpA # Primele doua caractere # Tot \c{s}irul \^{i}nafara de primele doua caractere

Iat inc un exemplu: a a


>>> word[:2] + word[2:] HelpA >>> word[:3] + word[3:] HelpA

Transmiterea unor parametrii greii, nu genereaz o eroare, pentru c n aceast problem Python este foarte elegant. st a a a a Astfel un indice care este prea mare va nlocuit cu dimensiunea sirului:

12

Capitol 3. O introducere scurta n Python

>>> word[1:100] elpA >>> word[10:] >>> word[2:1]

Indicii pot si numere negative, n acest caz se consider c indicele zero se a cel mai la dreapta: a a a
>>> word[-1] A >>> word[-2] p >>> word[-2:] pA >>> word[:-2] Hel # ultimul caracter # penultimul caracter # ultimele doua caractere # totul \^{i}nafara de ultimele doua caractere

Dar, atenie -0 este acelai lucru cu 0! t s


>>> word[-0] H # (deoarece -0 egal 0)

Indicii negativi mai mari n valoare absolut dect dimensiunea sirului sunt trunchiai.Acest lucru nu funcioneaz si a t t a la selectarea unui singur caracter ( nu a unei subsecvene ) : t
>>> word[-100:] HelpA >>> word[-10] # error Traceback (most recent call last): File "<stdin>", line 1, in ? IndexError: string index out of range

Mai jos avei un tabel care v va ajuta la nelegerea mecanismului de numerotare al unui sir de caractere: t a t
+---+---+---+---+---+ | H | e | l | p | A | +---+---+---+---+---+ 0 1 2 3 4 5 -5 -4 -3 -2 -1

Prima linie de numere reprezint leg tura indicilor pozitivi cu sirul. A doua linie reprezint corespondena dintre a a a t caracterele sirului si indicii negativi. Un subir de la i la j este format din toate caracterele dintre cei doi indici i, s respectiv j. Pentru indicii pozitivi lungimea subirului este dat de diferena indicilor m rginai, dac nici unul dintre s a t a s a ei nu este mai mare dect lungimea sirului. De exemplu lungimea subirului word[1:3] este 2. s Funcia len() ntoarce lungimea unui sir de caractere: t
>>> s = supercalifragilisticexpialidocious >>> len(s) 34

3.1. Utilizarea Python-ului drept calculator de birou

13

3.1.3

Siruri de caractere UNICODE

ncepnd cu versiunea 2.0 a limbajului Python, este pus la dispoziia programatorului un nou tip de dat , pentru mat a nipularea textelor: obiectul Unicode. Poate folosit pentru stocarea si manipularea datelor de tip Unicode(consultai t http://www.unicode.org/) si se integreaz foarte bine cu obiectele string existente, avnd un mecanism de a auto-conversie. Unicode are avantajul c stabilete o leg tur unic ntre un num r si orice caracter scris n scripturi moderne sau a s a a a a scripturi mai vechi. La nceput au existat numai 256 de numere ecare avnd asociat un caracter, si toate textele erau asociate unei pagini de cod(code page) care f cea leg tura ntre caractere si numerele asociate. acest lucru a creat foarte mult confuzie a a a odat cu internaionalizarea software-ului. Unicode rezolv aceste probleme asocind o singur pagin tuturor scripta t a a a urilor. Crearea sirurilor de caractere Unicode este la fel de simpl ca si crearea sirurilor obiniute : a s
>>> uHello World ! uHello World !

Caracterul u din faa sirului indic interpretorului c trebuie s creeze un sir Unicode din expresia care urmeaz . t a a a a Dac dorii s includei caractere speciale, o putei face foarte simplu folosind secvenele Unicode-Escape. Iat un a t a t t t a exemplu:
>>> uHello\u0020World ! uHello World !

Secvena \u0020 indic interpretorului s insereze caracterul cu ordinalul 0x0020 (caracterul spaiu) npoziia pret a a t t cizat . Bineneles c n acest mod pot introduse si alte caractere, chiar si cele obinuite, folosind valoarea ordinalua t a s lui s u ca ordinal Unicode. Datorit faptului c primele 256 de caractere Unicode sunt aceleai ca si n notaia standard a a a s t Latin-1, folosit n multe ari occidentale, procesul de introducere a caracterelor Unicode devine mult mai simplu. a t Pentru experi exist si un mod direct(raw-mode) identic ca cel fel ca pentru sirurile normale. naintea sirului trebuie t a ad ugat ur pentru ca Python s intre n modul Unicode direct. Conversiile \uXXXX sunt utilizate numai dac este a a a folosit un num r impar de caractere backslash(\, naintea caracterului u: a
>>> urHello\u0020World ! uHello World ! >>> urHello\\u0020World ! uHello\\\\u0020World !

Acest mod poate foarte util dac avei de introdus un num r mare de backslash-uri. a t a n afar de metodele de creare a sirurilor Unicode standard, Python ofer multe alte metode de a crea siruri Unicode. a a Funcia built-in unicode() permite accesarea tuturor CODECS-urilor Unicode (CODEC = COderDECoder). t Cteva dintre codic rile foarte cunoscute ale caror codex-uri au fost convertite sunt : Latin-1, ASCII, UTF-8 si a UTF-16. Ultimele dou permit stocarea caracterelor Unicode pe unul sau mai muli octei. Codicarea implicit este a t t a ASCII, care permite treacerea caracterelor cuprinse ntre 0 si 127, dar blochez celelalte caractere semnalnd eroare. a Cnd un sir Unicode este tip rit, scris ntr-un ier, sau convertit cu funcia str(), conversia pornete utiliznd a s t s codarea implicit . a

14

Capitol 3. O introducere scurta n Python

>>> u"abc" uabc >>> str(u"abc") abc >>> u"" u\xe4\xf6\xfc >>> str(u"") Traceback (most recent call last): File "<stdin>", line 1, in ? UnicodeError: ASCII encoding error: ordinal not in range(128)

Pentru a converti un sir Unicode ntr-un sir pe 8 bii utiliznd o anumit codicare, obiectele Unicode furnizeaz t a a metoda encode(), care are un singur argument, numele codului. Este de preferat ca numele codurilor s se scrie cu a litere mici.
>>> u"".encode(utf-8) \xc3\xa4\xc3\xb6\xc3\xbc

Dac avei datele intr-o anume codicare si dorii s obinei un sir Unicode corespondent din ele, folosii funcia a t t a t t t t unicode() cu numele codului ca al doilea argument.
>>> unicode(\xc3\xa4\xc3\xb6\xc3\xbc, utf-8) u\xe4\xf6\xfc

3.1.4

Liste

Python pune la dispoziia programatorului o serie de date structurate, folosite pentru a grupa, a aduna la un loc mai t multe valori. Cea mai exibil astfel de structur este lista. O list poate scris ca o serie de valori separate prin a a a a virgul , si aat ntre paranteze p trate. Elementele unei liste nu trebuie s e neap rat de acelai tip: a a a a a s
>>> a = [spam, eggs, 100, 1234] >>> a [spam, eggs, 100, 1234]

La fel ca si la siruri, primul element al unei liste are indicele 0. n acelai fel ca si la siruri, listele pot poziionate, s t concatenate si aa mai departe: s
>>> a[0] spam >>> a[3] 1234 >>> a[-2] 100 >>> a[1:-1] [eggs, 100] >>> a[:2] + [bacon, 2*2] [spam, eggs, bacon, 4] >>> 3*a[:3] + [Boe!] [spam, eggs, 100, spam, eggs, 100, spam, eggs, 100, Boe!]

3.1. Utilizarea Python-ului drept calculator de birou

15

Spre deosebire se siruri, elementele unei liste pot modicate:


>>> a [spam, eggs, 100, 1234] >>> a[2] = a[2] + 23 >>> a [spam, eggs, 123, 1234]

Funcia len() se aplic si listelor : t a


>>> len(a) 4

Utilizarea sublistelor este de asemenea posibil . Prin folosirea lor se poate modica chiar si dimensiunea listei : a
>>> # substituirea unor componente : ... a[0:2] = [1,12] >>> a [1,12,123,1234] >>> # eliminarea unor componente : ... a[0:2] = [] >>> a [123,1234] >>> # inserarea unor componente : ... a[1:1] = [bletch,xyzzy] >>> a [123,bletch,xyzzy,1234] >>> # inserarea unei liste la debutul ei ... a[:0] = a >>> a [123,bletch,xyzzy,1234,123,bletch,xyzzy,1234] >>> len(a) 8

Este posibil s creai liste din alte liste (de exemplu prin concatenare): a t
>>> >>> >>> 3 >>> [2, >>> 2 >>> >>> [1, >>> [2, q = [2, 3] p = [1, q, 4] len(p) p[1] 3] p[1][0] p[1].append(xtra) p [2, 3, xtra], 4] q 3, xtra] # See section 5.1

Observai c n ultimul exemplu , p[1] si q fac referire la acelai obiect. Vom reveni cu detalii despre semantica t a s obiectelor mai trziu. 16 Capitol 3. O introducere scurta n Python

3.2

Primii pa i n programare s

Bineneles c putem folosi Python si la alte lucruri dect pentru a aduna 2 cu 2. Putem de exmplu s gener m o t a a a subsecvena din sirul lui Fibonacci: t
>>> ... ... >>> ... ... ... 1 1 2 3 5 8 # Seria lui Fibonacci: # Suma a doua elemente reprezinta urmatorul element. a, b = 0, 1 while b < 10: print b a, b = b, a+b

Acest exemplu demonstreaz urm toarele noiuni: a a t Prima linie conine o atribuire multipl . Varibilele a si b iau valorile 0 respectiv 1. Pe ultima linie, de asemenea t a este folosit atribuirea multipl . Evaluarea expresiilor din partea dreapt a unei atribuiri se face nainte de orice a a a atribuire. Evaluarea se face de la stnga la dreapta. Bucla while se execut atta timp ct b < 10 (atta timp ct condiia este adev rat ). La fel ca n C, zero a t a a nseamn fals, si orice num r diferit de zero nseamn adev rat. Condiia poate un sir, un element de list , a a a a t a absolut orice. Orice secvena de lungime diferit de zero nseamn adev rat, si invers. Condiia folosit n t a a a t a acest exemplu este o comparaie. Comparatorii standard sunt la fel ca n C: <(mai mic), >(mai mare), ==(egal), t <=(mai mic sau egal), >=(mai mare sau egal), !=(diferit). Instruciunile din bucl sunt aliniate. Alinierea (indentation) reprezint modul n care Python grupeaz instrucit a a a t unile. Deocamdat (!) Python nu dispune de un editor n linie de comand inteligent, astfel nct alinierea, a a tabularea s se fac automat. Suntei deci obligat s folosii tab sau spaii pentru a realiza gruparea instruciua a t a t t t nilor. Cnd vei scrie programe Python vei folosi un editor de text. Majoritatea editoarelor de la ora actual t t a realizeaz automat tabularea. Pentru a ncheia un bloc de instuciuni trebuie introdus o linie goal pentru a a t a a indica editorului c editarea blocului de comenzi s-a ncheiat (editorul nu poate ghici cnd ai introdus ultima a t linie. Atenie! ecare instruciune dintr-un bloc de instruciuni trebuie s aib aceleai num r de spaii si taburi t t t a a s a t nainte, deci instruciunile trebuie s e perfect aliniate. t a Instruciunea print aeaz expresia pe care o primete ca parametru. Sirurile de caractere sunt aate f r t s a s s aa ghilimele, si un spaiu este inserat ntre elemente, astfel nct aarea diverselor valori s mearg de la sine: t s a a
>>> i = 256*256 >>> print Valoarea lui i este:, i Valoarea lui i este: 65536

O virgul la sfritul listei de parametrii ai instruciunii print, inhib saltul cursorului pe linia urm toare la a s t a a sfritul instruciunii: s t

3.2. Primii pa i n programare s

17

>>> a, b = 0, 1 >>> while b < 1000: ... print b, ... a, b = b, a+b ... 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987

Observai c interpretorul sare la linia urm toare nainte de a ncepe aarea, dac ultima linie a fost incomplet . t a a s a a

18

Capitol 3. O introducere scurta n Python

CAPITOL

PATRU

Structuri de control
n afar de buclele de tip while (explicate anterior), Python dispune de structurile de control obinuite, ntlnite si n a s celelalte limbaje.

4.1 Instruciuni if t
Poate c cea mai cunoscut instruciune de control este instruciunea if. Exemplu: a a t t
>>> >>> ... ... ... ... ... ... ... ... ... x = int(raw_input("Introduceti un numar \^{i}ntreg : ")) if x < 0: x = 0 print Negativul schimbat \^{i}nzero elif x == 0: print Zero elif x == 1: print Unul singur else: print Mai multi

Pot exista mai multe seciuni elif sau niciuna, iar seciunea else este opional . Cuvntul cheie elif este evident t t t a prescurtarea de la elseif, si este folositor pentru a evita tabularea excesiv . O secvena if..elif..elif a t funcioneaz ca un bloc case sau switch, secvene proprii altor limbaje . t a t

4.2

Instruciuni for t

Instruciunea for din Python difer un pic faa de ce a-i ntlnit n C sau Pascal. n loc de o iteraie dat de o progresie t a t t t a aritmetic (Pascal), sau de o iteraie foarte exibil , pentru care programatorul poate deni att pasul iteraiei, ct si a t a t condiia de oprire (C), iteraiile instruciunii Python for funcioneaz dup elementele unei secvene (sir sau list ). t t t t a a t a

19

>>> # Masoara marimea unor \c{s}iruri ... a = [cat, window, defenestrate] >>> for x in a: ... print x, len(x) ... cat 3 window 6 defenestrate 12

Nu este normal(i sigur) ca secvena iterat s e modicat n timpul secvenei for ( este cazul numai al secventelor s t a a a t modicabile, cum ar listele). Dac apare necesitatea de a modica secvena n timpul iteraiei, iteraia trebuie s e a t t t a asociat unei copii a secvenei. Notaia subsecventelor realizeaz o particularitate convenabil : a t t a a
>>> for x in a[:]: # copiaza intreaga lista ... if len(x) > 6: a.insert(0, x) ... >>> a [defenestrate, cat, window, defenetrate]

4.3

Funcia range() t

Dac este necesar o iteraie pe o mulime de numere, putei folosi funcia range() pentru a genera liste ce contin a a t t t t progresii aritmetice :
>>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Paramentrul furnizat funciei range() nu va niciodat un membru al secvenei. Este posibil ca funcia range() t a t t s genereze o secvena ncepnd cu un alt num r dect 0, sau raia progresiei aritmetice poate modicat : a t a t a
>>> range(5, 10) [5, 6, 7, 8, 9] >>> range(0, 10, 3) [0, 3, 6, 9] >>> range(-10, -100, -30) [-10, -40, -70]

Pentru a realiza o iteraie pe o mulime de numere folosii funciile range() si len() astfel: t t t t

20

Capitol 4. Structuri de control

>>> a = [Mary, had, a, little, lamb] >>> for i in range(len(a)): ... print i, a[i] ... 0 Mary 1 had 2 a 3 little 4 lamb

4.4

Instruciuni break si continue, si clauze else pentru bucle t

La fel ca n C, instruciunea break termin forat orice bucl while sau for. Instruciunea continue trece t a t a t necondiionat la urm toarea iteraie. Instruciunile iterative pot avea si o clauz else. Instruciunile din cadrul unei t a t t a t astfel de clauze else sunt executate atunci cnd bucla se termin odat cu terminarea listei (for) sau atunci cnd a a condiia buclei devine fals (pentru while) aceste instruciuni nu sunt executate dac bucla este terminat printr-o t a t a a instruciune break. Iat un exemplu care determin numerele prime pn la 10: t a a a
>>> for n in range(2, 10): ... for x in range (2, n): ... if n % x == 0: ... print n, egal cu, x, *, n/x ... break ... else: ... # bucla s-a epuizat f\u{a}ra sa g\u{a}seasc\u{a} un factor ... print n,este un numar prim ... 2 este un numar prim 3 este un numar prim 4 egal cu 2 * 2 5 este un numar prim 6 egal cu 2 * 3 7 este un numar prim 8 egal cu 2 * 4 9 egal cu 3 * 3

4.5

Instruciuni pass t

Instruciunea pass nu execut nimic. Poate folosit atunci cnd este necesar prezena sintactic a unei instruciuni, t a a a t a t f r ca aceasta s execute ceva: aa a
>>> while 1: ... pass # Asteapta pentru intrerupere de la tastatura ...

4.4. Instruciuni break si continue, si clauze else pentru bucle t

21

4.6

Funcii t

Putem crea o funcie care genereaz sirul lui Fibonacci pn la o limit arbitrar : t a a a a
>>> ... ... ... ... ... ... >>> ... 1 1 def fib(n): # Scrie \c{s}irul lui Fibonacci pana la n "Scrie \c{s}irul lui Fibonacci pana la n" a, b = 0, 1 while b < n: print b, a, b = b, a+b # Folosim func\c{t}ia creata fib(2000) 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

Cuvntul cheie def este primul din deniia unei funcii. Acesteia trebuie s i urmeze numele funciei si o list t t a t a parantezat de parametrii. Instruciunile care formeaz funcia ncep pe linia imediat urm toare si trebuie s e disa t a t a a tanate mai mult dect antetul funciei faa de margine. Prima instruciune din corpul funciei poate un sir de t t t t t caractere(opional), acest sir reprezentnd documentaia funciei(docstring = sirul de documentaie al funciei). Exist t t t t t a utilitare care genereaz documentaie pornind de la aceste siruri, deci este o practic bun s v folosii de aceast a t a a a a t a facilitate. Execuia unei funcii creaz o nou tabel de simboluri, folosit pentru variabilele locale. Altfel spus toate atribuirile t t a a a a din cadrul unei funcii vor stoca valorile n tabela de simboluri local . Atunci cnd interpretorul g sete un nume de t a a s variabil , nti caut n tabela de simboluri local , apoi n cea global si apoi n cea predenit . a a a a a Cu toate acestea variabilelor globale nu li se pot atribui valori n cadrul unei funcii, dect dac se folosete instrucit a s t unea global. Parametrii actuali ai unei funcii apelate sunt introdui n tabela de simboluri local a celei funcii nmomentul apel rii t s a t a ei. Astfel transferul aegumentelor se face utilizand apel prin valoare (unde valoare este totdeauna un obiect referina, t nu valoarea obiectului).1 Cnd o funcie apeleaz o alta funcie, este creat o nou tabel de simboluri pentru funcia apelat . t a t a a a t a Denirea unei funcii trece numele funciei n tabela de simboluri curent . t t a Funcia nou creat este recunoscut de interpretor ca o funcie denit de utilizator. n Python exist un mecanism de t a a t a a redenumire a funciilor: t
>>> fib <function object at 10042ed0> >>> f = fib >>> f(100) 1 1 2 3 5 8 13 21 34 55 89

Ai putea obiecta c funcia fib este o procedur nu o funcie. n Python, la fel ca nC, procedurile sunt funcii, numai t a t a t t c nu returneaz nici o valoare. Tehnic vorbind, procedurile returneaz totui o valoare, aceasta este None(niciuna). a a a s None este un cuvnt cheie (predenit). n mod normal valoarea None nu este aat de interpretor. Totui dac dorii s a s a t s v convingei c aa funcioneaz procedurile ncercai urm torul exemplu: a a t a s t a t a
1 De fapt, apel prin referina va putea mai bine descris, atunci daca un obiect modicabil este transmis, apelantul va vedea dac nurma apelarii t a obiectul s-a modicat ( un element inserat ntr-o list ). a

22

Capitol 4. Structuri de control

>>> print fib(0) None

Este foarte simplu s construim o funcie care ntoarce ca rezultat sirul lui Fibonacci: a t
>>> ... ... ... ... ... ... ... ... >>> >>> [1, def fib2(n): # Intoarce \c{s}irul lui Fibonacci pana la n "Intoarce o lista continand \c{s}irul lui Fibonacci pana la n" result = [] a, b = 0, 1 while b< n: result.append(b) # vezi mai jos a, b = b, a+b return result f100 = fib2(100) # apelarea func\c{t}iei f100 # afisarea rezultatului 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

Acest exemplu demonstreaz mai multe faciliti ale limbajului Python: a at Instruciunea return ntoarce rezultatul funciei. return f r nici un parametru ntoarce ca rezultat al t t aa funciei valoarea None. Putei folosi return f r parametrii pentru a ncheia execuia unei funcii nainte t t aa t t de a se ajunge la nalul instruciunilor din cadrul funciei. Valoarea None este de asemenea ntoars ca rezultat t t a al unei funcii atunci cnd au fost executate toate instruciunile procedurii. t t Instruciunea result.append(b) apeleaz o metod a obiectului result. O metod este o funcie care t a a a t aparine unui obiect. Metodele sunt apelate folosind sintaxa obj.metod(unde obj este un obiect, poate t a si o expresie, iar metod este numele metodei ce este apelat ). n funcie de tipul lor, obiectele pot avea diferite a a t metode. Este posibil s existe metode de tipuri diferite f r a se crea confuzii. Este de asemenea posibil s creai a aa a t obiecte si metode folosind clasele, dar despre clase vom discuta mai trziu. Metoda append este denit pentru a obiecte de tip list , si adaug un element la sfritul listei. n acest exemplu ar echivalent cu result = a a s a result + [b] dar mult mai ecient . a

4.7 Mai multe despre funcii t


Este posibil n Python s denim funcii cu un num r variabil de argumente. Exist trei modalitai de a realiza acest a t a a t lucru, care pot combinate.

4.7.1

Valori implicite pentru argumente

Cea mai util metod este s specicai valori implicite pentru argumente. n acest fel creai o funcie care poate a a a t t t apelat cu mai puine argumente dect a fost denit : a t a

4.7. Mai multe despre funcii t

23

def ask_ok(prompt, retries=4, complaint=Da sau nu va rog!): while 1: ok = raw_input(prompt) if ok in {d, da): return 1 if ok in {n, nu): return 0 retries = retries - 1 if retries < 0: raise IOError, refusenik user print complaint

Funcia denit mai sus poate apelat n dou moduri: t a a a ask_ok(Suntei sigur c dorii s ieii?) t a t a s t fiierul?, 2) s sau: ask_ok(Dorii s tergei t a s t

Valorile implicite sunt evaluate n timpul interpret rii deniiei funciei, deci urm toarea secvena a t t a t
i = 5 def f(arg=i): print arg i = 6 f()

va aa 5. s ATENTIE!!!: Valorile implicite sunt evaluate o singur dat . Avei grij atunci cnd valoarea implicit este un obiect a a t a a modicabil. De exemplu funcia urm toare acumuleaz ntr-o list argumentele ce i sunt transmise n timpul unor t a a a apeluri consecutive:
def f(a, L=[]): L.append(a) return L print f(1) print f(2) print f(3)

va aa s
[1] [1, 2] [1, 2, 3]

Dac nu dorii ca valoarea implicit s e reinut dup terminarea funciei, putei proceda ca n exemplul urm tor: a t a a t a a t t a
def f(a, L=None): if L is None: L = [] L.append(a) return L

24

Capitol 4. Structuri de control

4.7.2

Argumente de tip cuvinte cheie

Funciile pot apelate folosind n loc de argumente cuvinte cheie de forma: cuvant_cheie = valoare. Pentru t exemplicare observai funcia: t t
def parrot(voltage, state=mort, action=zboara, type=Norvegian Blue): print "-- Acest papagal nu", action print "daca pui", voltage, "volti prin el." print "-- Doamne!", type print "-- E ", state, "!"

care poate apelat n mai multe moduri: a


parrot(1000) parrot(action=BOOM, voltage=10000) parrot(o mie, state=apasa iarba) parrot(un milion, fara viata, sare)

Dar urm toarele apeluri ar genera erori: a


parrot() # Lipseste argumentul obligatoriu parrot(voltage=5.0, mort) # Dupa cuvantul cheie trebuie sa urmeze un argument tip cheie parrot(110, voltage=220) # Doua valori atribuite aceleia\c{s}i varibile parrot(actor=John Cleese) # Cuvant cheie necunoscut

n general o list de argumente trebuie s aibe oricte argumente poziionale, urmate de oricte argumente de tip a a t cuvinte cheie, unde cuvintele cheie trebuie alese din lista parametrilor formali. Nu este important dac un parametru a formal are o valoare implicit sau nu. Nici un argument nu poate primi o valoare de mai multe ori numele de a parametrii formali corespunz toare argumentelor poziionale nu pot folosite drept cuvinte cheie n cadrul aceluiai a t s apel. Iat un exemplu cu erori datorate acestei reguli: a
>>> def function(a): ... pass ... >>> function(0, a=0) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: keyword parameter redefined

Atunci cnd unul dintre parametrii este de forma **nume, funcia va primi o list care va conine parametrii de t a t tip cuvnt cheie. Dac se folosete un parametru de tipul *nume, funcia va primi o list coninnd argumentele a s t a t suplimentare n afara celor formale. Dac sunt folosii mpreun parametrul *nume trebuie s se ae naintea celui de a t a a tip **nume. Totul poate p rea ambiguu dar vei l murii imediat: a t a t
def cheeseshop(kind, *arguments, **keywords): print " - Aveti", kind, "?" print " - Nu, nu avem", kind for arg in arguments: print arg print -*40 for kw in keywords.keys(): print kw, :, keywords[kw]

Un apel al acestei funcii ar ar ta astfel: t a

4.7. Mai multe despre funcii t

25

cheeseshop(Limburger,"Se vinde foarte repede, d-le" "Se vinde foarte, FOARTE repede, d-le" client=John Cleese manager=Michael Palin sketch=Cheese Shop Sketch)

Iar rezultatul va urm torul: a


- Aveti Limburger? - Nu, nu avem Limburger Se vinde foarte repede, d-le. Se vinde foarte, FOARTE repede, d-le. ---------------------------------------client : John Cleese manager : Michael Palin sketch : Cheese Shop Sketch

4.7.3

Liste de argumente arbitrare

O funcie poate apelat cu un num r arbitrar de argumente. nainte de argumentele arbitrare (opionale) pot exista t a a t mai multe argumente normale:
def fprintf(file, format, *args): file.write(format % args)

4.7.4

Forme Lambda

La cererea utilizatorilor de Python, au fost ad ugate cteva faciliti specice limbajelor funcionale si Lisp-ului. a at t Folosind cuvntul cheie lambda putei crea mici funcii. Iat o funcie care ntoarce ca rezultat suma argumentelor: t t a t lambda a, b : a+b. Formele lambda pot folosite acolo unde sunt necesare funcii obiect. Aceste funcii t t sunt restrnse sintactic la o singur expresie: a
>>> ... ... >>> >>> 42 >>> 43 >>> def make_incrementor(n): return lambda x, incr=n: x+incr f = make_incrementor(42) f(0) f(1)

4.7.5

Sirurile de documentaie t

Exist anumite convenii privind coninutul si formatarea sirurilor de documentaie. a t t t Prima linie ar trebui s e scurt si foarte concis . Pentru concizie nu ar trebui precizat numele obiectivului sau tipul, a a a acestea ind subnelese. Aceast linie trebuie s nceap cu liter mare si s se termine cu virgul . t a a a a a a

26

Capitol 4. Structuri de control

Dac exist mai multe linii, cea de-a doua ar trebui s e vid , pentru a separa descrierea scurt de cea am nunit . a a a a a a t a Urm toarele linii ar trebui s descrie mai pe larg obiectul, semnicaia parametrilor, etc. a a t Interpretorul Python ia n consideraie spaiile din sirurile de caractere mp rite pe mai multe linii, din aceast cauz t t at a a pentru a avea o documentaie aranjat frumos trebuie s v folosii de un mic truc la fel ca n exemplul urm tor: t a a a t a
>>> def my_function(): ... " " "Nu face decat documentarea. ... ... Chiar nu face nimic! ... " " " ... pass ... >>> print my_function.__doc__ Nu face decat documentarea. Chiar nu face nimic!

4.7. Mai multe despre funcii t

27

28

CAPITOL

CINCI

Strucuri de date
Acest capitol subliniaz anumite lucruri deja cunoscute si descrie altele noi. a

5.1

Mai multe despre liste

Tipul de date list mai dispune de cteva metode. Iat toate metodele obiectelor de tip list : a a a append(x) Adaug un element la sfritul listei. a s extend(L) Adaug la sfritul listei, elementele listei furnizate ca parametru. a s insert(i, x) Insereaz un element ntr-o anumit poziie. Primul argument reprezint indicele elementului din a a t a list naintea c ruia se va face inseria, deci a.insert(0,x) va insera elementul x la nceputul listei, iar a a t a.insert(len(a),x) este echivalent cu a.append(x). remove(x) Sterge din list primul element g sit cu valoarea x. Dac nu exist un astfel de element apare o eroare. a a a a pop([i ]) Sterge din list elementul de pe poziia i, si ntoarce valoarea acestuia. Dac nu este specicat nici un a t a parametru a.pop(), va sterge si va returna ultimul element din list . a index(x) ntoarce indicele primului parametru din list care are valoarea x. a count(x) ntoarce num rul de apariii ale valorii x ntre elementele listei. a t sort() Sorteaz elementele listei. a reverse() Schimb ordinea elementelor din list . a a Iat un exemplu care folosete majoritatea metodelor: a s

29

>>> a = [66.6, 333, 333, 1, 1234.5] >>> print a.count(333), a.count(66.6), a.count(x) 2 1 0 >>> a.insert(2, -1) >>> a.append(333) >>> a [66.6, 333, -1, 333, 1, 1234.5, 333] >>> a.index(333) 1 >>> a.remove(333) >>> a [66.6, -1, 333, 1, 1234.5, 333] >>> a.reverse() >>> a [333, 1234.5, 1, 333, -1, 66.6] >>> a.sort() >>> a [-1, 1, 66.6, 333, 333, 1234.5]

5.1.1

Folosirea listelor drept stive

Obiectele de tip list pot folosite foarte uor pentru a simula comportamentul unei stive. Pentru a ad uga un element a s a pe stiv (PUSH), putei folosi append(). Pentru a scoate un element din stiv (POP), folosii pop() f r a specica a t a t aa un index. Iat un exemplu: a
>>> >>> >>> >>> [3, >>> 7 >>> [3, >>> 6 >>> 5 >>> [3, stack = [3, 4, 5] stack.append(6) stack.append(7) stack 4, 5, 6, 7] stack.pop() stack 4, 5, 6] stack.pop() stack.pop() stack 4]

5.1.2

Folosirea listelor drept cozi

Putei folosi listele foarte convenabil, pentru a implementa cozi. Spre deosebire de stive unde primul element ad ugat t a este ultimul scos, la cozi primul element ad ugat este primul scos. Pentru a ad uga un element folosii append(), a a t iar pentru a extrage un element folosii pop(0): t

30

Capitol 5. Strucuri de date

>>> queue = ["Eric", "Ion", "Mihai"] >>> queue.append("Razvan") >>> queue.append("Cristi") >>> queue.pop(0) Eric >>> queue.pop(0) Ion >>> queue [Mihai, Razvan, Cristi]

5.1.3

Instrumente de programare funcionala t

Exist trei funcii predenite care sunt foarte utile n lucrul cu liste: filter(), map(), reduce(). a t Funcia filter() cu sintaxa filter(funcie, secven), ntoarce o secvena format din elementele t t ta t a secvenei specicate ca parametru, care ndeplinete condiia testat de funcie. Exemplul care urmeaz calculeaz t s t a t a a numerele prime din intervalul 2, 25:
>>> def f(x): return x % 2 != 0 and x % 3 != 0 ... >>> filter(f, range(2, 25)) [5, 7, 11, 13, 17, 19, 23]

Funcia map() cu sintaxa map(funcie, secven), apeleaz funcia specicat ca parametru pentru ecare t t ta a t a element din secvena, si ntoarce o nou list format din rezultatele ntoarse de funcie. Pentru a calcula p tratele t a a a t a unor numere dintr-o list putei folosi o secvena similar celei ce urmeaz : a t t a a
>>> def cube(x): return x*x*x ... >>> map(cube, range(1, 11)) [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

Funcia map() accept ca parametrii mai multe secvene. n acest caz funcia transmis ca parametru trebuie s e t a t t a a modicat corespunz tor, trebuie s accepte acelai num r de parametrii cte secvene sunt transmise. Dac secvenele a a a s a t a t sunt diferite ca lungime, atunci cnd una dintre secvene s-a terminat, n loc de un element funciei i se transmite None. t t Dac n loc de un nume de funcie, se transmite None funciei map(), atunci funcia va nlocuit cu o funcie care a t t t a t va ntoarce ca rezultat parametrii primii. Putei folosi comportamentul funciei map() pentru a genera perchi de t t t numere provenind din dou liste: a
>>> seq = range(8) >>> def square(x): return x*x ... >>> map(None, seq, map(square, seq)) [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25), (6, 36), (7, 49)]

Funcia reduce(funcie, secvena) ntoarce o simpl valoare care este calculat n felul urm tor: este t t t a a a apelat funcia (care este obligatoriu o funcie binar ce accept numai 2 parametrii), cu parametrii primul si al doilea a t t a a termen al secvenei, funcia ntoarce un rezultat care mpreun cu al treilea element sunt transmise din nou funciei, t t a t care genereaz un alt rezultat si aa mai departe, pn ce lista este epuizat . a s a a

5.1. Mai multe despre liste

31

Exemplul de mai jos calculeaz suma primelor numere naturale: a


>>> def add(x,y): return x+y ... >>> reduce(add, range(1, 11)) 55

Dac exist un singur element n secvena valoarea acestuia va returnat . Dac lista este goal , va generat a a t a a a a o excepie. Funcia reduce() poate primi si un al treilea parametru care semnic valoarea de la care ncepe t t a calculul. n acest caz primul apel al funciei are ca parametrii aceast valoare si primul element al listei. Dac funcia t a a t reduce() este apelat cu trei parametrii, iar lista este goal , aceasta va ntoarce ca rezultat al treilea parametru. Iat a a a un exemplu care ilustreaz modul de lucru al funciei reduce(): a t
>>> def sum(seq): ... def add(x,y): return x+y ... return reduce(add, seq, 0) ... >>> sum(range(1, 11)) 55 >>> sum([]) 0

5.1.4

Un alt mod de a genera liste

Exist un mod de a crea liste mult mai concis dect prin intermediul funciilor map(), filter() sau lambda(). a t Deniia listei este de cele mai multe ori mult mai clar dect cea obinut prin alte metode. Acest mod generalizat, de t a t a a genera, a deni liste const n asocierea unei expresii, cu o clauz for si cu niciuna sau mai multe clauze for sau a a if. Rezultatul va o list care provine din evaluarea expresiei n contextul clauzelor for si if ce urmeaz . Dac a a a rezultatul evalu rii expresiei va o pereche, atunci expresia trebuie parantezat corespunz tor: a a a

32

Capitol 5. Strucuri de date

>>> freshfruit = [ banana, loganberry , passion fruit ] >>> [weapon.strip() for weapon in freshfruit] [banana, loganberry, passion fruit] >>> vec = [2, 4, 6] >>> [3*x for x in vec] [6, 12, 18] >>> [3*x for x in vec if x > 3] [12, 18] >>> [3*x for x in vec if x < 2] [] >>> [{x: x**2} for x in vec] [{2: 4}, {4: 16}, {6: 36}] >>> [[x,x**2] for x in vec] [[2, 4], [4, 16], [6, 36]] >>> [x, x**2 for x in vec] # error - parens required for tuples File "<stdin>", line 1, in ? [x, x**2 for x in vec] ^ SyntaxError: invalid syntax >>> [(x, x**2) for x in vec] [(2, 4), (4, 16), (6, 36)] >>> vec1 = [2, 4, 6] >>> vec2 = [4, 3, -9] >>> [x*y for x in vec1 for y in vec2] [8, 6, -18, 16, 12, -36, 24, 18, -54] >>> [x+y for x in vec1 for y in vec2] [6, 5, -7, 8, 7, -5, 10, 9, -3]

5.2 Instruciunea del t


Exist o metod de a sterge un element dintr-o list specicnd indicele elementului n loc de valoarea elementua a a lui. Aceast metod poate folosit si pentru a sterge poriuni dintr-o list . Toate acestea pot realizate utiliznd a a a t a instruciunea del: t
>>> a [-1, 1, 66.6, 333, 333, 1234.5] >>> del a[0] >>> a [1, 66.6, 333, 333, 1234.5] >>> del a[2:4] >>> a [1, 66.6, 1234.5]

del poate folosit si pentru a sterge variabile, de exemplu o ntreag list : a a a


>>> del a

Vom vedea mai trziu si alte modaliti de a utiliza instruciunea del. at t

5.2. Instruciunea del t

33

5.3
1

Perechi si secvene t

Am obsevat pn acum c listele si sirurile de caractere au multe caracteristici comune, de exemplu: indexarea si a a poziionarea (slicing). Sirurile si listele sunt dou exemple de tipuri de date secvena. Deoarece Python este un limbaj t a t care evolueaz , n timp pot ad ugate si alte tipuri de date secvena. Exist si un alt tip standard de date: perechea a a t a (enumerarea). O pereche, o enumerare este format din mai multe valori separate prin virgule: a
>>> t = 12345, 54321, hello! >>> t[0] 12345 >>> t (12345, 54321, hello!) >>> # enumerarile pot fi imbricate, combinate ... u = t, (1, 2, 3, 4 ,5) >>> u ((12345, 54321, hello!), (1, 2, 3, 4 ,5))

Dup cum putei vedea perechile(enumer rile) sunt aate ntre paranteze astfel nct enumer rile sau perechile mbria t a s a cate s e interpretate corect. Perechile pot introduse cu sau f r paranteze, ns , adesea parantezele sunt necesare. a aa a Perechile au multe utiliz ri. De exemplu : perechi de coordonate (x,y), nregistr rile angajailor dintr-o baz de date, a a t a etc. Putei face o analogie (atta timp ct r mne numai o analogie menit s v ajute la nelegerea acestui tip de t a a a a t date) ntre tipurile de date compuse ce pot denite cu struct din C++, si perechile din Python. Perechile, la fel ca sirurile nu pot modicate: nu pot atribuite valori unui anumit element al unei perechi (putei ns s simulai t a a t o modicare folosind alte metode). Este posibil s creai perechi care conin obiecte modicabile, cum sunt listele de a t t exemplu. O problem deosebit o constituie crearea perechilor cu zero sau un element. Exist ns cteva trucuri de sintax a a a a a care pot folosite pentru a rezolva aceast problem . Perechile vide pot construite folosind o pereche de paranteze a a f r nimic ntre ele. O pereche cu un singur element poate construit specicnd valoarea care va coninut n aa a t a pereche urmat de o virgul . Cam nepl cut, dar funcioneaz : a a a t a
>>> empty = () >>> singleton = hello, >>> len(empty) 0 >>> len(singleton) 1 (hello,)

# <---- observati virgula

Instruciunea t = 12345, 54321, Salut! este un exemplu de mpachetare. Valorile 12345, 54321 si t Salut! sunt mpachetate mpreun . Operaia invers este de asemenea posibil : a t a a
>>> x, y, z = t

Aceast operaie este numit sucient de elocvent despachtarea unei secvene. Despachetarea unei secvene necesit a t a t t a ca lista de variabile de la stnga atribuirii s conin tot attea variabile ct secvena mpachetat de la dreapta. De a t a t a observat este faptul c mbricarea nu este dect o combinaie succesiv de mpachet ri sau despachet ri! Ingenios, a t a a a nu?! Exist o asimetrie aici: n timp ce o mpachetare va genera ntotdeauna o pereche, despachtarea funcioneaz pentru a t a
1

N.T. termenul romnesc PERECHE este impropriu, forma original ind TUPLE. a

34

Capitol 5. Strucuri de date

orice fel de secvena. t

5.4

Dicionare t

Un alt tip de date predenit n Python si care se poate dovedi foarte folositor este dicionarul. Dicionarele pot t t ntlnite si n alte limbaje, sub alte nume, cum ar memorii asociative sau valori asociative. Spre deosebire de secvene (liste, siruri, etc.) care sunt indexate cu numere (indicii sunt numere), dicionarele sunt indexate de chei, care t t pot denite de oricare din tipurile de date invariabile(nemodicabile), de exemplu: siruri de caractere sau numere. Perechile pot folosite drept chei ale unui dicionar numai dac conin obiecte invariabile. Nu putei folosi drept chei t a t t listele deoarece acestea pot modicate folosind metode ca append() sau extend(). Este indicat s v gndii la un dicionar ca la o mulime neordonat de perechi cheie-valoare, cu observaia c o cheie a a t t t a t a trebuie s e unic ntr-un dicionar. O pereche de acolade creaz un dicionar gol: {}. Putei crea un dicionar dac a a t a t t t a ntre acolade introducei o list (ale c rei elemente sunt separate prin virgul ), de perechi cheie-valoare: dicionar t a a a t = jack:4098, Sape:4139. Operaiile principale pe care le realizeaz un dicionar sunt: stocarea unei t a t valori cu anumit cheie si extragerea unei valori cunoscndu-se o anumit cheie. O pereche cheie-valoare poate a a stears folosind instruciunea del. Dac se adaug o valoare n dicionare pentru o cheie care exist deja, valoarea a t a a t a veche asociat acelei chei este pierdut . O eroare este generat , bineneles, dac vei ncerca s extragei o valoare a a a t a t a t pentru o cheie inexistent . a Metoda keys() a unui obiect dicionar ntoarce o list cu toate cheile existente n respectivul dicionar. Lista returnat t a t a nu este sortat , ns pentru a o sorta putei folosi metoda sort() a obiectului list returnat de funcie. Pentru a verica a a t a t dac o anumit cheie se a deja n dicionar folosii metoda has-key(). Iat un mic exemplu: a a a t t a
>>> tel = {jack: 4098, sape: 4139} >>> tel[guido] = 4127 >>> tel {sape: 4139, guido: 4127, jack: 4098} >>> tel[jack] 4098 >>> del tel[sape] >>> tel[irv] = 4127 >>> tel {guido: 4127, irv: 4127, jack: 4098} >>> tel.keys() [guido, irv, jack] >>> tel.has_key(guido) 1

5.5 Mai multe despre condiii t


Condiiile folosite n cadrul instruciunilor while sau if pot conine si ali operatori dect cei de comparaie. t t t t t Operatorii de comparaie in si not in veric dac o anumit valoare se a sau nu ntr-o secvena dat . Operatorii t a a a a t a is si is not veric dac dou obiecte sunt de fapt unul si acelai obiect, acest lucru conteaz n cazul obiectelor a a a s a modicabile cum sunt listele de exemplu. Operatorii de comparaie pot combinai. De exemplu a < b == c testeaz nti dac a < b iar apoi dac b este t t a a a egal cu c. Condiiile pot avea structuri foarte complexe dac sunt folosii operatorii and, or sau not. Operatorii de t a t comparaie au aceeai prioritate care este mai mic dect aceea a operatorilor numerici. Operatorii logici, t s a booleeni(and,or,not) au cea mai mic prioritate, mai mic dect aceea a operatorilor de comparaie. Cea mai a a t mare prioritate ntre operatorii logici o au not, apoi and, iar cea mai mic or. n concluzie A and not B or a 5.4. Dicionare t 35

C este echivalent cu A and (not B) or C. Bineneles putei folosi paranteze pentru a combina condiiile si t t t pentru claritate. Operatorii logici mai sunt denumii si operatori pe scurt tur (shortcut operator), argumentele acestea sunt evaluate t a a de la stnga la dreapta, si evaluarea se oprete odat ce rezultatul este determinat. De exemplu dac A si C sunt s a a adev rate, iar B fals, expresia A and B and C nu este evaluat pn la sfrit, deci expresia C nu este evaluat a a a s a pentru c ar inutil. a Este posibil atribuirea unei valori rezultate dintr-o comparaie sau orice alt condiie, unei variabile: a t a t
>>> string1, string2, string3 = , Trondheim, Hammer Dance >>> non_null = string1 or string2 or string3 >>> non_null Trondheim

Spre deosebire de C, n Python nu sunt permise atribuirii n cadrul expresiilor. Programatorii de C pot critica acest lucru, dar prin aceasta se evit o mulime de erori ntlnite n programele C, de exemplu = n loc de ==. a t

5.6 Compararea secvenelor t


Obiectelor de tip secvena pot comparate cu obiecte secvena de acelai tip. Comparaiile ntre secvene folosesc t t s t t principiile ordon rii lexicograce: sunt comparate nti primele dou elemente din ecare list , dac difer rezultatul a a a a a este aat, dac sunt egale se trece la compararea urm toarelor dou elemente, si aa mai departe pn la epuizarea s a a a s a uneia dintre liste. Dac elementele ce urmeaz a comparate sunt la rdul lor liste, compararea lexicograc are loc a a a recursiv. Dac toate elementele celor dou liste sunt egale se consider c listele sunt egale. Dac una dintre secvene a a a a a t este o subsecvenaa iniial a celeilalte, atunci secvena mai scurt este cea mai mic . Ordonarea lexicograc pentru t t a t a a a siruri folosete ordinea ASCII a caracterelor. Exemple de comparaii ntre secvence de acelai tip: s t t s
(1, 2, 3) < (1, 2, 4) [1, 2, 3] < [1, 2, 4] ABC < C < Pascal < Python (1, 2, 3, 4) < (1, 2, 4) (1, 2) < (1, 2, -1) (1, 2, 3) == (1.0, 2.0, 3.0) (1, 2, (aa, ab)) < (1, 2, (abc, a), 4)

Se pot compara obiecte de tipuri diferite. Rezultatul este ns arbitrar: tipurile ind ordonate dup numele lor. n a a concluzie o list va ntotdeauna mai mic dect un sir, un sir mai mic dect o pereche, etc. Comparaiile ntre a a t numere se fac lund n consideraie valoarea numeric chiar dac numerele sunt de tipuri diferite, si ca atare 0 va t a a egal cu 0.0, etc. 2

2 Regulile de comparaie ntre obiecte de tipuri diferite nu ar trebui considerate de foarte mare ncredere, deoarece acestea pot schimbate la t versiuni viitoare ale limbajului.

36

Capitol 5. Strucuri de date

CAPITOL

SASE

Module
Dac ieii din interpretorul Python si intrai din nou, deniiile pe care le-ai f cut (funcii, varibile, etc.) se pierd. a st t t t a t Dac avei de gnd s scriei un program mai lung, ar mai bine s folosii un editor de texte pentru a scrie programul a t a t a t ntr-un ier, si apoi s rulai interpretorul Python cu parametru ierul n care se a programul. Fiierul n care se s a t s a s a programul se numete script. Pe m sur ce programul se va m ri vei simi nevoia s l mp rii n mai multe a s a a a t t a att iere. S-ar putea la fel de bine s dorii s folosii o funcie n mai multe programe f r a nevoit s copiai deniia s a t a t t aa a t t funciei n ecare program. t n Python putei scrie anumite deniii ntr-un ier, pe care l putei include n alte programe. Un astfel de ier t t s t s se numete modul. Deniiile dintr-un modul pot importate n alte module, sau n modulul principal (programul s t iniial). Un modul este un ier care conine deniii si instruciuni Python. Numele ierului n care se a un t s t t t s a anumit modul este dat de numele modulului si extensia .py la sfrit. ntr-un modul, numele acestuia este accesibil s prin intermediul variabilei globale __name__. Folosii acum editorul dumneavoastr de texte preferat pentru a creea t a ierul bo.py: s
# modul cu numerele lui Fibonacci def fib(n): # scrie \c{s}irul lui Fibonacci pana la n a, b = 0, 1 while b < n: print b, a, b = b, a+b def fib2(n): # intoarce \c{s}irul lui Fibonacci pana la n result = [] a, b = 0, 1 while b < n: result.append(b) a, b = b, a+b return result

Acum deschidei interpretorul Python si tastai comanda: t t


>>> import fibo

Aceast instruciune nu ncarc n tabela de simboluri numele funciilor denite n modulul bo, ci numai numele a t a t modulului. Folosind numele modulului putei accesa funciile denite n interiorul acestuia: t t

37

>>> fibo.fib(1000) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 >>> fibo.fib2(100) [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] >>> fibo.__name__ fibo

n cazul n care v deranjeaz aceste nume lungi putei proceda n felul urm tor: a a t a
>>> fib = fibo.fib >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377

6.1

Mai multe despre module

Un modul poate conine att instruciuni executabile ct si deniii de funcii. Aceste instruciuni sunt menite s t t t t t a realizeze iniializarea modulului si se execut o singur dat atunci cnd modulul este importat. t a a a Fiecare modul are propria sa tabel de simboluri care este folosit de funciile denite n modul ca o tabel de simboluri a a t a global . a Cu toate astea, autorul unui modul se poate folosi de variabilele globale, f r a-i face griji pentru eventuale coliziuni aa s cu variabilele globale ale mediului n care modulul va importat. Pe de alt parte dac avei neap rat nevoie putei a a t a t modica direct variabilele globale ale unui modul, folosind aceeai convenie ca la apelarea funciilor unui modul: s t t modul.variabil. a Modulele pot importa alte module. Instruciunile import pot plasate la nceputul programului si este indicat, dar t nu este obligatoriu. Exist o metod de a nc rca deniiile unui anumit modul direct n tabela de simboluri global a modulului care a a a t a import : a
>>> from fibo import fib, fib2 >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377

n exemplul de mai sus, numele modulului nu a fost introdus n tabela de simboluri local . Pentru a nc rca toate a a deniiile modulului direct n tabela local folosii: t a t n exemplul de mai sus, n tabela local au fost nc rcate toate numele de variabile si funcii, mai putin cele care ncep a a t cu caracterul _.
>>> from fibo import * >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377

6.1.1

Calea n care sunt cautate modulele

Atunci cnd un modul numit xxx este importat, interpretorul caut un ier numit xxx.py n directorul curent, si n a s toate directoarele specicate n variabila de sistem PYTHONPATH. Aceasta are aceeai sintaxa variabila de sistem s

38

Capitol 6. Module

PATH, care este o list a directorului. Dac variabila PYTHONPATH nu este denit modulul va c utat n directorul a a a a implicit de instalare, de obicei /usr/local/lib/python.

6.1.2

Fi iere Python compilate s

Un important aport de vitez la pornirea programelor care ncarc o mulime de module standard este adus de urm torul a a t a comportament al Python-ului: dac n directorul unde este g sit ierul xxx.py se mai a si xxx.pyc, se presupune a a s a c acest ultim ier conine o variant compilat a modulului si este nc rcat n loc de xxx.py. Timpul la care a fost a s t a a a modicat ultima oar ierul .py este nregistrat n ierul .pyc n momentul n care este creat, iar n momentul a s s importului dac aceste momente de timp nu corespund ierului .pyc este ignorat. a s De obicei nu trebuie s facei nimic deosebit pentru a crea ierul xxx.pyc. Oridecteori xxx.py este compilat cu a t s succes este creat sau suprascris si ierul xxx.pyc. Dac scrierea ierului compilat nu reuete vei avertizat printr s a s s s t un mesaj de eroare. Coninutul ierelor de tip .pyc este independent de platform , astfel nct Python devine un t s a limbaj foarte portabil. Cteva indicaii pentru experi: t t Cnd interpretorul Python este apelat folosind opiunea -O, se genereaz cod optimizat care va stocat n iere t a s de tip .pyo. La momentul actual optimizatorul nu este de prea mare folos, nu face dect s elimine din cod a instruciunile assert si SET-LINENO. Atunci cnd se folosete aceast opiune tot codul este optimizat, t s a t ierele .pyc sunt ignorate iar ierele .py sunt compilate si optimizate. s s Dac interpretorul Python este lansat n execuie folosind opiunea -O, compilatorul poate genera n anumite a t t cazuri cod compilat eronat. Versiunea curent elimin sirurile __doc__ din codul compilat, astfel nct acesta a a s e mai compact. Din moment ce unele programe pot folosi aceste siruri, eliminarea lor ar putea genera erori. a n concluzie, ar trebui s folosii aceast opiune numai atunci cnd stii foarte bine ce facei. a t a t t t Un program nu funcioneaz mai rapid, atunci cnd este citit dintr-un ier de tip .pyc sau .pyo, faa de unul t a s t .py. Singurul lucru care difer este viteza de nc rcare a programelor n memorie. a a Atunci cnd un script este rulat, prin lansarea interpretorului si parametru numele ierului n care se a script s a ul, codul script-ului nu este compilat si nu se genereaz iere de tip .pyc sau .pyo. n cazul n care avei un a s t script de dimensiuni mari, si dorii s cretei viteza de nc rcare, putei s mutai buci din cod ntr-un modul t a s t a t a t at pe care s l importai apoi n script. Interpretorul Python poate lansat si folosind direct un ier cu extensia a t s .pyc sau .pyo. Este posibil s lansai interpretorul Python doar cu un ier de tip .pyc (sau .pyo dac se folosete -O), f r a t s a s aa ca ierul .py asociat s existe. Putei folosi aceast facilitate atunci cnd distribuii o bibliotec si nu dorii s s a t a t a t a e modicat . a Modulul compileall poate folosit pentru a crea iere .pyc sau .pyo pentru toate modulele dintr-un s director.

6.2

Module standard

Python dispune de o bilbliotec de module standard, a c ror descriere o putei g si ndocumentul The Python Library a a t a Reference. Unele module sunt integrate n interpretor, dei nu fac parte din nucleul limbajului, din deniia acestuia, s t dar sunt integrate pentru eciena sau pentru a facilita accesul la primitivele sistemului de operare. Setul de module t integrate este o optiune de congurare, care de asemenea depinde de particularitatea platformei. De exemplu modulul amoeba este disponibil pe sisteme care pun la dispoziie primitive Amoeba. Un anumit modul necesit o atenie t a t special : sys care este integrat n orice interpretor Python. Variabilele sys.ps1 si sys.ps2 denesc sirurile de a caractere ce vor folosite de interpretor pentru prompt-ul principal si cel secundar:

6.2. Module standard

39

>>> import sys >>> sys.ps1 >>> >>> sys.ps2 ... >>> sys.ps1 = C> C> print Yuck! Yuck! C>

Aceste dou variabile sunt denite doar dac interpretorul se a n mod interactiv. Variabila sys.path conine o lis a a a t a de directoare unde Python caut module. Aceast variabil este iniializat din variabila de sistem PYTHONPATH, sau a a a t a cu o valoare implicit n cazul n care PYTHONPATH nu este denit . Putei modica sys.path folosind operaii a a t t specice listelor:
>>> import sys >>> sys.path.append(/ufs/guido/lib/python)

6.3

Funcia dir() t

Funcia integrat dir() poate folosit pentru a determina ce nume(de variabile, funcii, etc.) denete un modul. t a a t s Rezultatul acestei funcii este o list sortat de siruri de caractere: t a a
>>> import fibo, sys >>> dir(fibo) [__name__, fib, fib2] >>> dir(sys) [__name__, argv, builtin_module_names, copyright, exit, maxint, modules, path, ps1, ps2, setprofile, settrace, stderr, stdin, stdout, version]

Dac funcia dir() este apelat f r argumente, va lista numele ce sunt denite (local) pn n momentul curent: a t a aa a
>>> a = [1, 2, 3, 4, 5] >>> import fibo, sys >>> fib = fibo.fib >>> dir() [__name__, a, fib, fibo, sys]

Observai c listeaz diferite tipuri de nume: variabile, funcii, module, etc. t a a t dir() nu listeaz si numele de funcii sau variabile integrate. Dac dorii o astfel de list , putei apela a t a t a t dir(__builtin__), unde __buildin__ este modulul n care se a funciile si variabilele integrate: a t

40

Capitol 6. Module

>>> import __builtin__ >>> dir(__builtin__) [AccessError, AttributeError, ConflictError, EOFError, IOError, ImportError, IndexError, KeyError, KeyboardInterrupt, MemoryError, NameError, None, OverflowError, RuntimeError, SyntaxError, SystemError, SystemExit, TypeError, ValueError, ZeroDivisionError, __name__, abs, apply, chr, cmp, coerce, compile, dir, divmod, eval, execfile, filter, float, getattr, hasattr, hash, hex, id, input, int, len, long, map, max, min, oct, open, ord, pow, range, raw_input, reduce, reload, repr, round, setattr, str, type, xrange]

6.4

Pachete

Pachetele sunt o modalitate prin care Python structureaz modul de acces la module(i la deniiile existente n moda s t ule). Pentru exemplicare numele modulului A.B desemneaz un submodul B denit n cadrul pachetului A. a S presupunem c dorii s proiectai o colecie de module (un pachet) pentru manipularea ierelor de sunet, si a a a t a t t s sunetelor. Exist o multitudine de formate de sunet (de obicei recunoscute dup extensia lor .wav, .aiff, .au) aa a a s c este necesar creearea si ntreinerea unei colecii de module ncontinu cretere care s permit conversia ntre a a t t a s a a diverse formate de iere. Exist multe alte operaii pe care poate ai dori s le executai (mixaje, ad ugarea ecoului, s a t t a t a efecte stereo, etc.), aa c , de fapt, vei scrie o serie nesfrit de module care s permit aceste operaii. Avei mai jos s a t s a a a t t o posibil structur a pachetului dumneavoastr (n sensul unei ierahii de iere): a a a s
Sound/ __init__.py Formats/ __init__.py wavread.py wavwrite.py aiffread.py aiffwrite.py auread.py auwrite.py ... Effects/ __init__.py echo.py surround.py reverse.py ... Filters/ __init__.py equalizer.py vocoder.py karaoke.py ... Pachet "tata" Initializarea pachetului sound Subpachet pentru conversii intre fi\c{s}iere

Subpachet pentru efecte acustice

Subpachet pentru filtre

Fiierele de tipul __init__.py sunt necesare pentru a face Python s trateze directoarele ca pachete. Acestea sunt s a necesare pentru a preveni situaia ca un director cu un nume comun, de exemplu string, s ascund un modul valid t a a cu acelai nume. n cel mai simplu caz __init.py__ poate un ier gol, dar poate conine si cod de iniializare. s s t t Utilizatorii unui pachet pot importa doar un anumit modul din cadrul pachetului: 6.4. Pachete 41

import Sound.Effects.echo

Instruciunea de mai sus a nc rcat modulul Sound.Effects.echo, dar o funcie din cadrul modulului trebuie t a t aplelat folosindu-i numele ntreg. a
Sound.Effects.echo.echofilter(input, output, delay=0.7, atten=4)

O alternativ pentru a importa un modul este: a


from Sound.Effects import echo

n acest moment numele denite n modul au fost nc rcate n tabela local de simboluri, deci numele de funcii si a a t variabile sunt disponibile f r prex: aa
echo.echofilter(input, output, delay=0.7, atten=4)

O alt variant este nc rcarea (importarea) direct a funciei sau variabilei dorite: a a a a t
from Sound.Effects.echo import echofilter

Un exemplu de utilizare a funciei echofilter(): t


echofilter(input, output, delay=0.7, atten=4)

De observat c atunci cnd se folosete sintaxa from packet import element, elementul poate , e un submodul a s (sau subpachet), e un nume denit n pachet, de exemplu un nume de funcie sau variabil , sau un nume de clas . t a a Instruciunea import testeaz nti dac elementul este denit sau nu n pachet. Dac elementul nu este denit, t a a a Python presupune c este vorba de un modul si ncearc s -l ncarce. Dac nc rcarea nu reuete este generat o a a a a a s s a excepie de tipul ImportError. t Cnd folosii o sintax de genul: import element.subelement.subsubelement, ecare element, mai t a puin ultimul trebuie obligatoriu s e un pachet. Ultimul element poate un modul, un pachet, dar nu poate o t a clas , o funcie, o variabil , etc. denit n elementul anterior. a t a a

6.4.1

Importarea tuturor modulelor dintr-un pachet

Ce se va ntmpla dac un programator va folosi o instruciune de genul: from Sound.Effects import *? a t ntr-un caz ideal, programatorul ar putea s spere c interpretorul Python va realiza o c utare recursiv n sistemul de a a a a iere si directoare dup modulele existente n pachet. Din nefericire nu funcioneaz foarte bine pe platforme Mac s a t a sau Windows, din varii motive. Pe astfel de platforme existena unui ier ECHO.PY nu garanteaz c n acest ier t s a a s se a un modul numit Echo, ct si echo sau ecHo, si aa mai departe. Spre exemplu Windows 95 are prostul obicei a s de a aa numele de iere cu prima liter mare. Sistemul de iere DOS 8+3 ridic o alt piedic n calea numelor s s a s a a a lungi de module. Singura soluie pentru astfel de probleme este ca autorul pachetului s specice exact ce module exist n pachet. t a a Instruciunea import() folosete urm toarea convenie: dac codul existent n ierul __init__.py denete o list t s a t a s s a cu numele __all__, aceasta este considerat lista cu modulele ce ar trebui nc rcate la execuia unei instruciuni a a t t from pachet import *. Este obligaia autorului pachetului s modice lista atunci cnd este cazul. Autorii de t a pachete pot lua de asemenea decizia de a nu deni aceast list , dac nu vor ca programatorul care folosete pachetul a a a s s execute instruciuni de genul import *. Fiierul Sounds/Effects/__init__.py ar trebui s conin urm toarele: a t s a t a a 42 Capitol 6. Module

__all__ = ["echo", "surround", "reverse"]

n acest caz instruciunea from Sound.Effects import * ar nc rca cele trei submodule ale modulului t a Sound. Dac variabila __all__ nu este denit , instruciunea de import nu va importa toate submodulele ci va importa a a t numai pachetul Sound.Effects (eventual va executa codul de iniializare din __init__.py) si apoi va importa toate t numele denite n pachet. Se vor importa si submodulele pachetului dac acest lucru este specicat prin instruciuni a t import. Privii urm torul cod : t a
import Sound.Effects.echo import Sound.Effects.surround from Sound.Effects import *

n exemplul anterior, modulele echo si surround sunt importate deoarece acest lucru este specicat (prin instruciuni t import) n cadrul pachetului Sound.Effects. Nu este foarte ecient s folosii instruciuni de tipul import *, pentru c n acest fel codul dumneavoastr va a t t a a deveni neclar, neind clar care anume module sunt nc rcate. Totui dac ai lansat interpretorul n mod interactiv, a s a t putei folosi astfel de instruciuni pentru a evita scrierea multor instruciuni. t t t n concluzie nu este nimic greit n folosirea unei instruciuni similare cu from Packet import submodul, de fapt s t aceasta este notaia recomandat . t a

6.4.2

Referenieri ntre pachete t

Apare deseori necesitatea ca ntr-un submodul s apar un alt submodul. De exemplu modulul surround s-ar putea a a folosi de modulele echo. De fapt astfel de referine sunt att de ntlnite nct instruciunea import examinaez nti t t a pachetul cel mai cuprinz tor, si apoi caut n lista de directoare. Cu toate astea modulul surround poate folosi a a mult mai simplu o instruciune import echo sau from echo import echolter. Dac modulul ce se dorete t a s importat nu se a n pachetul curent, instruciunea import caut mai sus n ierarhia de modul a pachetului. a t a Atunci cnd pachetele sunt strucuturate n subpachete, nu exist o modalitate de a prescurta referirile la alte submoda ule, ci trebuie folosite numele ntregi ale subpachetelor. De exemplu dac modulul Sound.Filters.vocoder a are nevoie de modulul echo din pachetul Sound.Effects, poate folosi instruciunea: from Sound.Effects t import echo.

6.4. Pachete

43

44

CAPITOL

SAPTE

s Intrari si ie iri
Exist cteva modaliti de a prezenta rezultatele unui program. Datele pot aate ntr-un format care poate neles a at s t de om, sau pot scrise ntr-un ier pentru a putea prelucrate mai trziu. Acest capitol va explica cteva dintre s posibiliti. at

7.1

Formatarea mai eleganta a datelor la ie ire s

Pn acum am ntlnit dou metode de a aa valori: instruciunea print si expresii. (O a treia metod este folosind a a s t a metoda write() a obiectelor de tip ier. Fiierul standard de ieire este referit ca sys.stdout.) s s s Adesea vei dori s avei mai mult control asupra modului de aare a valorilor. Exist dou metode pentru a controla t a t s a a modul de aare: prima este s modicai singur un sir de caractere, folosind diversele operaii existente, iar apoi s s a t t a l aai. Modulul string conine cteva operaii utile pentru manipularea sirurilor de caractere. O a doua metod s t t t a este folosirea operatorului %, cu un sir, ca argument stnga. Operatorul % interpreteaz argumentul stnga n acelai a s mod ca si sirul de formatare al funciei C sprintf() aplicndu-l asupra argumentului din dreapta si returnnd sirul t rezultat n urma ecestei format ri. O singur ntrebare r mne: cum pot convertite valorile n siruri de caractere? a a a Din fericire Python poate converti orice tip de valoare n sir de caractere: e prin funcia repr(), e scriind valoarea t ntre apostroafe (). Iat cteva exemple: a Pn acum am ntlnit dou metode de a aa valori: instruciunea print si expresii. (O a treia metod este folosind a a s t a write() a obiectelor de tip ier. Fiierul standard de ieire este referit ca sys.stdout.) s s s
>>> x = 10 * 3.25 >>> y = 200 * 200 >>> s = Valoarea lui x este + x + , \c{s}i a lui y este + y + ... >>> print s Valoarea lui x este 32.5, \c{s}i a lui y este 40000... >>> # Apostroafele inverse operea\u{a} \^{i}n alt fel asupra numerelor : ... p = [x, y] >>> ps = repr(p) >>> ps [32.5, 40000] >>> # Convertirea unui \c{s}ir ad\u{a}ug\^{a}nd apostroafe \c{s}i backslashe-uri: ... hello = hello, world\n >>> hellos = hello >>> print hellos hello, world\n >>> # Argumentele unor apostroafe inverse pot fi perechi ( tuple ) : ... x, y, (spam, eggs) "(32.5, 40000, (spam, eggs))"

Iat dou modaliti de a genera un tabel cu p tratele si cuburile numerelor naturale: a a at a 45

>>> import string >>> for x in range(1, 11): ... print string.rjust(x, 2), string.rjust(x*x, 3), ... # Observati ultimul caracter "," de pe ultima linie ... print string.rjust(x*x*x, 4) ... 1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000 >>> for x in range(1,11): ... print %2d %3d %4d % (x, x*x, x*x*x) ... 1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000

Observai c ntre coloane a fost ad ugat un spaiu. Acest comportament este asigurat de modul n care lucreaz t a a t a instruciunea print: ntotdeauna adaug un spaiu ntre argumentele sale. t a t Acest exemplu demonstreaz utilizarea funciei string.rjust(), care aliniaz la dreapta un sir de caractere, a t a ntr-un cmp de o anumit dimensiune dat , introducnd spaii la stnga sirului. Exist si alte funcii similare a a t a t string.ljust(), string.center(). Aceste funcii nu aeaz nimic, nu fac dect s returneze un alt sir t s a a de caractere. Dac sirul primit este mai lung, aceste funcii nu l modic , ci l returneaz intact. Acest mecana t a a ism probabil c v va strica aranjarea pe coloane, dar este o variant preferabil celeilalte, adic trunchierea sira a a a a ului. Dac dorii s truchiai un sir, putei oricnd s folosii operaiile de porionare (slicing), ca de exemplu: a t a t t a t t t string.ljust(x,n)[0:n]. Mai exist o funcie util , care umple cu zero-uri un sir, ad ugndu-le la stnga sirului original, pn cnd acesta a t a a a ajunge la o anumit dimensiune. Aceast funcie este string.zfill(): a a t
>>> import string >>> string.zfill(12, 5) 00012 >>> string.zfill(-3.14, 7) -003.14 >>> string.zfill(3.14159265359, 5) 3.14159265359

Folosind operatorul % ar ar ta astfel: a

46

s Capitol 7. Intrari si ie iri

>>> import math >>> print Valoarea lui PI este aprox. %5.3f. % math.pi Valoarea lui PI este aprox. 3.142.

Dac exist mai multe format ri n sir, trebuie s se transmita ca operator dreapta o pereche ( tupla ), astfel : a a a a
>>> table = {Sjoerd: 4127, Jack: 4098, Dcab: 7678} >>> for name, phone in table.items(): ... print %-10s ==> %10d % (name, phone) ... Jack ==> 4098 Dcab ==> 7678 Sjoerd ==> 4127

Majoritatea tipurilor de formate funcioneaz exact ca n C, si nu necesit dect transmiterea corect a operandului t a a a din dreapta. Nerespectarea acestei reguli va genera o excepie. Specicatorul de format %s este mai exibil, dac t a parametrul asociat din partea dreapt nu este de tip sir de caractere, va automat convertit la sir de caractere folosind a funcia integrat str(). Specicatorii de format %u si %p din C nu sunt acceptai si de Python. t a t Dac avei un sir lung pe care nu dorii s -l mp rii n mai multe siruri, ar interesant s v putei referi la varia t t a att a a t abile prin nume n loc de poziie. Acest lucru poate realizat folosind modalitatea numevariabil format, ca t a nurmatorul exemplu :
>>> table = {Sjoerd: 4127, Jack: 4098, Dcab: 8637678} >>> print Jack: %(Jack)d; Sjoerd: %(Sjoerd)d; Dcab: %(Dcab)d % table Jack: 4098; Sjoerd: 4127; Dcab: 8637678

Acest lucru se poate dovedi foarte util atunci cnd dorii s aai variabilele predenite folosind funcia vars() care t a s t t ntoarce un dicionar cu toate variabilele locale. t

7.2

Fi iere s

Funcia open() are ca rezultat un obiect de tip ier, si este de cele mai multe ori apelat cu doi parametrii: numele t s a de ier si modul de acces la ier: s s
>>> f=open(/tmp/workfile, w) >>> print f <open file /tmp/workfile, mode w at 80a0960>

Primul argument este un sir de caractere care conine numele ierului ce urmeaz s e deschis. Al doilea argument t s a a este tot un sir de caractere ce conine doar cteva caractere ce descriu modul n care ierul va utilizat. Modul poate t s : - r = ierul va putea numai citit s - w = ierul va putea dect s e scris (n cazul n care un ier exist deja, acesta va suprascris) s a s a - a = ierul va deschis pentru actualizare (toate datele scrise vor ad ugate la sfritul ierului) s a s s - r+ = n ierul ce va deschis se pot executa att operaii de scriere ct si de citire. s t 7.2. Fi iere s 47

Pe Windows si Macintosh ad ugarea caracterului b la sfritul sirului prin care se specic modul de acces, indic a s a a interpretorului Python s deschid ierul n mod binar. Exist deci modurile de acces rb, wb, r+b. Windows face a a s a distincie ntre ierele de tip text si cele binare: caracterele de sfrit de linie sunt modicate atunci cnd se scriu sau t s s se citesc date. Aceaste modic ri din spatele scenei sunt binevenite n cazul ierelor text, dar nu pot face dect r u a s a n cazul ierelor binare cum sunt .JPG sau .EXE de exemplu. Avei deci grij s folosii modul binar cnd lucrai s t a a t t cu astfel de iere. s

7.2.1

Metodele obiectelor ier s

Exemplele acestei seciuni vor presupune c un obiect f de tip ier a fost deja creat, deci ierul a fost deja deschis. t a s s Pentru a citi coninutul unui ier apelai f.read(dimensiune), care citete o cantitate de date si o returneaz t s t s a ca string. Parametrul dimensiune este opional. Atunci cnd acest parametru este omis sau este negativ, ntregul ier t s va citit si returnat ca sir de caractere. Apare o problem bineneles dac memoria mainii dumneavoastr este mai a t a s a mic dect dimensiunea ierului. Dac parametrul dimensiune este transmis funciei din ier vor citii cel mult a s a t s t atia bytes ci sunt specicai prin acest parametru. t t t Dac s-a ajuns la sfritul ierului f.read() va returna un sir vid(" "): a s s
>>> f.read() This is the entire file.\n >>> f.read()

Metoda f.readline() citete o singur linie din ier. Un caracter linie nou (newline), \n este ad ugat la s a s a a sfritul ec rui sir. Acest caracter este omis dac este vorba despre ultima linie din ier si dac acesta nu se termin s a a s a a cu un caracter linie nou . Toate acestea fac rezultatul neclar. Dac rezultatul este un sir gol, atunci a fost atins a a sfritul ierului, n timp ce dac rezultatul este doar caracterul \n nseamn c din ier a fost citit o linie goal : s s a a a s a a
>>> f.readline() This is the first line of the file.\n >>> f.readline() Second line of the file\n >>> f.readline()

Metoda f.readlines() a obiectelor de tip ier, ntoarce o list coninnd toate liniile din ier. Dac metoda s a t s a este apelat cu argumentul dimensiune, atunci din ier sunt citii atia bytes ci sunt specicai prin acest parametru a s t t t t si nc atia bytes ci sunt necesari pentru a completa o linie. Aceast metod este folosit pentru citirea ecient pe a t t a a a a linii a ierelor de dimensiuni mari f r a ntmpina diculti cu memoria. Vor returnate numai linii complete: s aa at
>>> f.readlines() [This is the first line of the file.\n, Second line of the file\n]

Metoda write(ir) scrie coninutul sirului de caractere n ier, ntorc nd None ca rezultat: s t s a
>>> f.write(This is a test\n)

f.tell() are ca rezultat un num r ntreg reprezentnd poziia cursorului n ier, poziie m surat n bytes faa a t s t a a t de nceputul ierului. Pentru a schimba poziia cursorului folosii funcia f.seek(deplasare,referin). s t t t ta 48 s Capitol 7. Intrari si ie iri

Noua poziie este calculat n felul urm tor: cursorul va deplasat cu deplasare bytes, faa de nceputul ierului t a a t s dac referin este 0, faa de poziia curent a cursorului dac referin este 1 si faa de sfritul ierului a ta t t a a ta t s s dac referin este 2. Dac al doilea parametru este omis, valoarea lui implicit va 0, deci punctul de referina a ta a a t va nceputul ierului: s
>>> >>> >>> >>> 5 >>> >>> d f=open(/tmp/workfile, r+) f.write(0123456789abcdef) f.seek(5) # Go to the 5th byte in the file f.read(1) f.seek(-3, 2) # Go to the 3rd byte before the end f.read(1)

Cnd terminai lucrul cu un ier, acesta trebuie nchis folosind f.close(). Dup nchiderea ierului orice ncert s a s care de operaie asupra ierului va eua: t s s
>>> f.close() >>> f.read() Traceback (most recent callk last): File "<stdin>", line 1, in ? ValueError: I/O operation on closed file

Obiectele ier posead si alte metode, cum ar isatty() si truncate() care sunt mai puin folosite. (Consultai s a t t "Python Library Refference" pentru mai multe detalii).

7.2.2

Modulul pickle

Sirurile de caractere pot citite si scrise foarte uor dintr-un, respectiv ntr-un ier. Cu numerele lucrurile se complic s s a puin. Ai putea s transformai nainte de scrierea n ier, num rul n string, apoi s l scriei, iar la citire s l t t a t s a a t a transformai napoi n num r, dar un astfel de mecanism este complet inecient. t a Pentru aceste situaii, si altele mult mai complicate Python dispune de modulul pickle care poate transforma orice t obiect Python ntr-un string. Acest proces se cheam pickling, denumirea procesului invers se numete unpickling. a s ntre aceste dou proceduri string-ul poate salvat ntr-un ier, transmis n reea, etc. a s t Cea mai simpl metod de a salva un obiect ntr-un ier este urm toarea: a a s a
pickle.dump(x, f)

Iar pentru a nc rca un obiect dintr-un ier: a s


x = pickle.load(f)

Exist si alte metode de a transforma un obiect ntr-un sir f r a-l salva ntr-un ier. Pentru mai multe detalii consultai a aa s t Python Library Refference. Prin procedeele de pickling si unpickling, pickle poate stoca obiecte ce pot apoi reutilizate. Termenul tehnic pentru un astfel de obiect este obiect persistent. Deoarece aceste metode sunt foarte des folosite, programatorii care creeaz extensii ale limbajului Python au grij ca tipurile de date nou denite s poat salvate si nc rcate corect(mai a a a a a bine zis s se comporte corect n procesul de pickling si apoi unpickling). a

7.2. Fi iere s

49

50

CAPITOL

OPT

Erori si excepii t
Pn acum erorile au fost doar menionate, dar dac ai ncercat exemplele prezentate probabil ai si ntlnit cteva a t a t t dintre ele. Exist (cel puin) dou categorii de erori: erori de sintax si excepii. a t a a t

8.1

Erori de sintaxa

Erorile de sintax sunt cel mai des ntlnite erori atta timp ct suntei un ncep tor n limbajul Python: a t a
>>> while 1 print Hello world File "<stdin>", line 1, in ? while 1 print Hello world ^ SyntaxError: invalid syntax

Interpretorul reproduce linia care a cauzat eroarea si aeaz o s geat n dreptul instrucinii care a generat eroarea. s a a a t Eroarea este cauzat (sau cel puin detectat ) de instruciunea dinaintea s geii. n exemplul de mai sus eroarea este a t a t a t generat de instruciunea print, deoarece naintea acestei instruciuni ar trebui s existe un caracter :. Numele a t t a ierului si num rul liniei care a generat eroarea sunt aate, astfel nct dac eroarea provine dintr-un script s putei s a s a a t corecta ct mai comod.

8.2

Excepii t

Chiar dac o expresie sau o instruciune este corect din punct de vedere sintactic, aceasta poate genera o eroare n a t a momentul n care este executat . Erorile generate (detectate) n timpul execuiei se numesc excepii, si nu sunt neap rat a t t a fatale. Vei ntreba cum putei evita astfel de erori utiliznd limbajul Python. t t Majoritatea excepiilor nu sunt tratate de program si genereaz mesaje de eroare ca n exemplul de mai jos: t a

51

>>> 10 * (1/0) Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: integer division or modulo >>> 4 + spam*3 Traceback (most recent call last): File "<stdin>", line 1, in ? NameError: spam >>> 2 + 2 Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: illegal argument type for built-in operation

Ultima linie a mesajului de eroare indic ce s-a ntmplat. Excepiile sunt de diferite tipuri, iar tipul excepiei este a t t de asemenea aat n corpul mesajului de eroare. n exemplul anterior: ZeroDivisionError, NameError si s TypeError, sirul aat ce desemneaz tipul excepiei este un nume predenit pentru respectivul tip de excepie. s a t t Acest lucru este valabil pentru toate excepiile predenite, dar se pot deni si alte tipuri de excepii. t t A doua parte a liniei reprezint detaliile excepiei, descriind mai bine ce s-a ntmplat. a t n Python Library Reference sunt listate excepiile implicite si semnicaiile lor. t t

8.3 Tratarea excepiilor t


Este posibil s scriei programe care trateaz anumite tipuri de excepii . n urm torul exemplu este implementat o a t a t a a bucl care cere utilizatorului introducerea unui num r. Bucla este ntrerupt n momentul n care utilizatorul introduce a a a un num r corect, astfel procesul de introducere continu . Procesul poate ntrerupt folosind combinaia de taste a a t CTRL-C. Dac utilizatorul folosete aceast combinaie de taste, programul este ntrerupt, dar nainte este generat a s a t a excepia: KeyboardInterrupt: t
>>> while 1: ... try: ... x = int(raw_input("Please enter a number: ")) ... break ... except ValueError: ... print "Oops! That was no valid number. Try again..." ...

Instruciunea try funcioneaz n felul urm tor: t t a a nti sunt executate instruciunile din blocul try (blocul de instruciuni dintre instruciunile try si except). t t t Dac nu este generat nici o excepie, instruciunile din blocul except nu sunt executate si programul continu . a a t t a Dac apare o excepie n timpul execuiei instruciunilor din blocul try si dac tipul excepiei este acela pe care a t t t a t l trateaz si blocul except, atunci instruiunile din acest bloc nu sunt executate. Dup ce excepia este tratat , a t a t a execuia continu , nemai executndu-se instruciunile r mase din blocul try (adic instruciunile ce urmeaz t a t a a t a dup instruciunea care a generat excepia). a t t Dac excepia nu este prev zut ntre excepiile tratate n blocul except, ea este transmis altor structuri a t a a t a try.Dac nu este g sit un bloc except care s trateze excepia, programul este ntrerupt, iar respectiva excepie a a a t t se numete excepie netratat (unhandled exception). s t a

52

Capitol 8. Erori si excepii t

O instruciune try poate avea mai multe clauze except, implementnd astfel mai multe tipuri de tratament pentru t mai multe tipuri de excepii. Dintre toate clauzele except va executat cel mult una. Instruciunile unei clauze t a t except, trateaz numai excepiile generate n blocul try c ruia clauza i este asociat , nu si excepiile ce pot apare a t a a t n alte clauze except. O astfel de clauz poate trata mai multe tipuri de excepii desemnate printr-o lista inchis ntre a t a paranteze, ca de exemplu :
... except (RuntimeError, TypeError, NameError): ... pass

Ultima clauz except poate folosit f r a se specica ce anume excepie trateaz , n acest caz aceast clauz a a aa t a a a trateaz toate excepiile netratate de celelalte clauze. Putei folosi aceast ultim precauie, si este indicat s o facei, a t t a a t a t pentru a ascunde toate erorile ce pot ap rea si pe care nu le-ai anticipat. O putei de asemenea folosi pentru a aa un a t t s mesaj de eroare si apoi a regenera excepia, care va transmis mai departe, urmnd s e eventual tratat de un alt t a a a bloc try:
import string, sys try: f = open(myfile.txt) s = f.readline() i = int(string.strip(s)) except IOError, (errno, strerror): print "I/O error(%s): %s" % (errno, strerror) except ValueError: print "Nu poate fi convertit \^{i}ninteger" except: print "Eroare neasteptata:", sys.exc_info()[0] raise

Instruciunile try dispun si de o clauz opional : else. Atunci cnd aceasta este folosit , ea trebuie s e ultima t a t a a a dintre clauze. Instruciunile acestei clauze vor executate atunci cnd, blocul try nu genereaz nici o excepie. Iat t a t a un exemplu:
for arg in sys.argv[1:]: try: f = open(arg, r) except IOError: print cannot open, arg else: print arg, has, len(f.readlines()), lines f.close()

Utilizarea clauzei else este mai adecvat dect ad ugarea unor linii suplimentare de cod la sfritul blocului try, a a s pentru c n acest fel se evit detectarea unei excepii care nu a fost generat de instruciunile blocului try. a a t a t O excepie poate avea asociat si o valoare, un argument al excepiei. Prezena argumentului si tipul acestuia depinde t a t t de tipul excepiei. Pentru acele excepii care au un argument, clauza except poate avea nume de varibil , dup t t a a numele excepiei, variabil ce va conine(dac acea excepie este detectat ) argumentul asociat excepiei. Urm torul t a t a t a t a exemplu este l muritor n acest sens: a

8.3. Tratarea excepiilor t

53

>>> try: ... spam() ... except NameError, x: ... print name, x, undefined ... name spam undefined

Dac o excepie are un argument, acesta va aat n ultima parte a mesajului ce apare cnd o excepie nu este tratat . a t s t a ntr-un bloc try nu sunt detectate numai excepiile generate n cadrul funciilor apelate: t t
>>> def this_fails(): ... x = 1/0 ... >>> try: ... this_fails() ... except ZeroDivisionError, detail: ... print Handling run-time error:, detail ... Handling run-time error: integer division or modulo

8.4

Generarea excepiilor t

Instruciunea raise i permite programatorului s genereze o anumit excepie : t a a t


>>> raise NameError, HiThere Traceback (most recent call last): File "<stdin>", line 1, in ? NameError: HiThere

Primul parametru reprezint tipul excepiei, iar al doilea este opional si reprezint un eventual argument. a t t a Dac se vrea s se stie cnd o excepie a fost semnalata , dar nu se intenioneaz tratarea ei, o form mai simplicata a a t a t a a a a instruciunii raise permite reapariia excepiei : t t t
>>> try: ... raise NameError, HiThere ... except NameError: ... print An exception flew by! ... raise ... An exception flew by! Traceback (most recent call last): File "<stdin>", line 2, in ? NameError: HiThere

54

Capitol 8. Erori si excepii t

8.5

Excepii denite de utilizator t

Un programator i poate crea propriile excepii prin creare unei clase de excepii noi. n mod obinuit excepiile pot s t t s t derivate din clasa Exception att nmod direct ct si indirect. De exemplu :
>>> class MyError(Exception): ... def __init__(self, value): ... self.value = value ... def __str__(self): ... return self.value ... >>> try: ... raise MyError(2*2) ... except MyError, e: ... print My exception occurred, value:, e.value ... My exception occurred, value: 4 >>> raise MyError, oops! Traceback (most recent call last): File "<stdin>", line 1, in ? __main__.MyError: oops!

Clasele de excepii pot proiectate ca oricare alta clas , dar in mod uzual ele sunt simple, deseori oferind numai un t a num r de atribute, ce permit s informeze asupra erorii ce a fost tratat . Cnd se implementeaz un modul care poate a a a a genera un num r distinct de erori, se obinuiete s se creeze o clasa de baz a excepiilor denite de acest modul, si a s s a a t subclase care s creeze clase specice pentru diferite condiii de eroare : a t

8.5. Excepii denite de utilizator t

55

class Error(Exception): """Base class for exceptions in this module.""" pass class InputError(Error): """Excetie generat\u{a} pentru eroare de intrare. Atribute: expression -- expresia de intrare \^{i}n care apare eroarea message -- explicarea erorii """ def __init__(self, expression, message): self.expression = expression self.message = message class TransitionError(Error): """Generata c\^{a}nd o opera\c{t}ie a\c{s}teapt\u{a} o modificare de stare care nu este permis\u{a} Attributes: previous -- starea la \^{i}nceputul tranzi\c{t}iei next -- noua stare care este de a\c{s}tept s\u{a} apar\u{a} message -- explica\c{t}ie privind imposibilitatea tranzi\c{t}iei """ def __init__(self, previous, next, message): self.previous = previous self.next = next self.message = message

Multe excepii sunt denite cu nume care se termina n Error, similar cu denumirea excepiilor standard. t t Multe module i denesc propriile excepii pentru a raporta erorile ce pot ap rea nfunciile denite de ele. Mai multe s t a t informaii despre clase vei g si n capitolul refclasses, Classes.. t t a

8.6

t Denirea aciunilor de curaare t

Instruciunea try poate avea si o alt clauz prin care se pot deni aciuni de curare care vor executate n orice t a a t at circumstana. De exemplu: t
>>> try: ... raise KeyboardInterrupt ... finally: ... print Goodbye, world! ... Goodbye, world! Traceback (most recent call last): File "<stdin>", line 2, in ? KeyboardInterrupt

Clauza nally este executat dac a fost sau nu generat o excepie n blocul try. Cnd apare o excepie, este a a a t t regenerat dup ce sunt executate instruciunile clauzei finally. Clauza finally este de asemenea executat la a a t a 56 Capitol 8. Erori si excepii t

ieire, chiar si atunci cnd a fost apelat o instruciune break sau return. s a t Codul scris ncalauza finally este util pentru eliberarea resurselor externe (cum ar iere sau conect ri la reea), a s a t fara a mai vedea daca utilizarea resurse s-a ncheiat cu succes. O instruciune try trebuie e s aibe una sau mai multe clauze except, e o clauz finally, dar nu ambele n t a a acelai timp. s

t 8.6. Denirea aciunilor de curaare t

57

58

CAPITOL

NOUA

Clase
Mecanismul de clase al limbajului Python face posibil ad ugarea de noi clase cu un minim de efort. Acest mecanism a a de clase este o combinaie ntre mecanismele din C++ si Modula-3. La fel ca si pentru module, Python nu creeaz o t a barier absolut ntre deniie si utilizator, ci se bazeaz mai mult pe politeea utilizatorului de a nu p trunde n a a t a t a deniie. Cele mai importante faciliti ale claselor sunt n continuare disponibile. t at n terminologie C++, toate componentele unei clase(i datele membre) sunt publice, si toate funciile membre sunt s t virtuale. Nu exist constructori sau destructori specializai. La fel ca n Modula-3, nu exist scurt turi pentru a accesa a t a a membrii unei clase n cadrul unei metode a acelui obiect: metodele sunt denite cu un argument explicit reprezentnd obiectul, care este apoi transmis automat n momentul n care funcia este apelat . Clasele sunt n sine obiecte, iar n t a sens mai larg: n Python toate tipurile de date sunt obiecte, acest comportament este specic si limbajului SmallTalk. Prin toate acestea sunt posibile importurile si redenumirile. La fel ca n C++ si Modula-3, tipurile predenite nu pot denite drept clase de baz pentru eventuale extensii. De asemenea, la fel ca n C++, dar spre deosebire de Modula-3, a majoritatea operatorilor cu sintax special (de exemplu: operatorii aritmetici) pot redenii n cadrul claselor. a a t

9.1

Cteva cuvinte despre terminologie

Deoarece nu exist o terminologie unanim recunoscut n ceea ce privete clasele, nu vom folosi aici termenii din a a s SmallTalk si C++. Am putea folosi termenii din Modula-3, deoarece semantica acestui limbaj este mai aproape de cea a Python-ului, dar foarte puini utilizatori au auzit de acest limbaj, dei C++ si SmallTalk sunt o alegere mult mai t s bun , ind limbaje cu o popularitate mult mai mare. a Va trebui de asemenea s avertiz m cititorii asupra unei greeli pe care o pot face n interpretarea celor ce urmeaz : a a s a cuvntul obiect n Python nu nseamn neap rat o instaniere a unei clase. n C++, Modula-3, de asemenea si n a a t Python, dar nu si n SmallTalk, exist anumite tipuri de date care nu sunt neap rat clase: numerele ntregi si listele nu a a sunt clase, dar si alte tipuri de date mai exotice, cum sunt ierele nu sunt clase. Toate tipurile de date n Python s au aproximativ acelai comportament care este mai uor de explicat dac ne referim la aceste tipuri de date folosind s s a cuvntul obiect. Obiectele pot avea individualitate, sau pot avea mai multe nume(care pot servi mai multor scopuri) care s desemneze a acelai obiect. Aceast procedeu se numete aliasing n alte limbaje. De obicei n Python, la prima vedere, nu sunt ns s curajate astfel de tehnici, care pot foarte bine ignorate cnd este vorba despre tipurile de date nemodicabile(numere, siruri, perechi). n orice caz, tehnica aceasta, aliasing, are si un efect intenionat asupra sintaxei Python care privete t s obiectele alterabile (liste, dicionare, etc.) si obiectele ce exist n afara contextului n care se a programul (iere, t a a s ferestre. etc.). Putei utiliza tehnica aliasing, pentru a benecia de puterea oferit n alte limbaje, de pointeri, nt a truct putei considera c alias-urile funcioneaz ntr-un anumit sens ca pointerii din C. Spre exemplu transmiterea t a t a unui obiect este mai simpl , din moment ce se transmite doar un pointer. Dac o funcie primete ca parametru un a a t s obiect pe care l modic , cel ce a aplelat funcia va putea observa efectul funciei, deoarece modic rile efectuate a t t a de funcie au fost f cute asupra coninutului obiectivului si nu asupra unui reprezent ri locale(n contextul funciei). t a t a t Explicnd toate acestea se observ necesitatea a dou mecanisme de transmitere a parametrilor ca n Pascal. a a

59

9.2
1

Domenii de vizibilitate (Scopes) si domenii de deniie a nu t melor(Name Spaces)

Deniiile claselor manipuleaz ntr-un mod foarte interesant domeniile de deniie a numelor, si o foarte bun t a t a nelegere a modului de funcionare a domeniilor de vizibilitate si de deniie a numelor este foarte impotant . t t t a nelegerea acestor mecanisme este foarte important si se va dovedi foarte util oric rui programator avansat Python. t a a a S ncepem cu cteva deniii: a t Un domeniu de deniii a numelor este o hart de leg turi ntre nume si obiecte. n momentul de faa aceste domenii t a a t sunt implementate folosind dicionare, dar metodele de implementare pot schimbate pe viitor. Exemple de astfel t de domenii sunt: domeniul numelor predenite, domeniul numelor globale dintr-un modul, domeniul numelor locale creat la apelarea unei funii, etc. ntr-un anumit sens atributele unui anumit obiect formeaz un domeniu de deniie. t a t Un lucru foarte important de stiut este acela c ntre dou nume existente n dou domenii diferite nu exist absolut a a a a nici o leg tur . Din aceast cauz dou module pot deni o funcie cu aceeai denumire f r a se creea confuzie. a a a a a t s aa Un atribut este orice nume care urmeaz unui punct, de exemplu n expresia z.real,real este un atribut al obiectului a z. ntr-un sens strict, referinele la nume denite ntr-un modul sunt de fapt referine la atribute ale modulului: n t t expresia modul.funcie, modul este modulul iar funcie este un atribut al modulului. t t Numele globale ale modulului si atributele modulului se a n acelai domeniu de deniie al numelor.(Exist o a s t a singur excepie. Modulele au un atribut nemodicabil (read-only) secret: __dict__ n care se a domeniul de a t a deniie al numelor ce aparine modulului. __dict__ este un atribut dar nu este un nume global.) t t Atributele pot nemodicabile(read-only) sau modicabile(writeable). Atributele unui modul sunt modicabile: putei folosi o secvena de genul: modul.rspuns = 42. Atributele modicabile pot de asemenea sterse t t a folosind operatorul del. De exemplu del modul.rspuns va elimina atributul rspuns din obiectul denumit a a modul. Domeniile de deniie a numelor sunt create la momente de timp diferite si au perioade de viaa diferite. Domeniul t t care conine numele predenite este creat odat cu pornirea interpretorului Python si nu este sters niciodat . Domeniul t a a numelor globale denite ntr-un modul este creat atunci cnd este nc rcat deniia modulului si este distrus de a a t obicei tot n momentul n care interpretorul este nchis. Instruciunile executate la primul nivel al interpretorului e t dintr-un script, e interactiv, fac parte dintr-un modul numit __main__. Numele predenite se a n domeniul a __builtin__. Domeniul de deniie a numelor pentru o funcie este creat odat cu apelul funciei, si este sters odat cu terminarea t t a t a funciei, e prin return, e dac acesta genereaz o excepie netratat . Bineneles c apeluri recursive genereaz t a a t a t a a mai multe domenii de deniie. t Un domeniu de vizibilitate (scope) este o regiune a unui program Python n care un anumit domeniu de deniie a t numelor este accesibil. Accesibil nseamn c o anumit referina la un nume va genera o c utare n domeniul de a a a t a deniie al acelui modul dspre care spunem c este accesibil. t a Domeniile de vizibilitate sunt determinate static, si sunt folosite dinamic. n timpul execuiei exist exact trei domenii t a de vizibilitate (exact trei domenii de deniie sunt direct accesibile): primul cel mai adnc, conine numele locale, t t cel de-al doilea conine numele globale ale modulului curent, iar cel de-al treilea cel mai de sus, care este ultimul n t care se caut un nume(dac n celelalte c utarea nu a avut succes, si care conine numele predenite. a a a t De obicei, cel mai adnc domeniu de vizibilitate este cel al funciei care este executat . n exteriorul unei funcii, t a t acest domeniu este identic cu al doilea domeniu (cel din mijloc), n care se a accesibile deniiile modulului. a t Domeniul de vizibilitate global al unei funcii denite ntr-un modul este domeniul de deniii al respectivului modul, t t indiferent de unde, sau cu ce alias este apelat respectiva funcie. Pe de alt parte c utarea unui anumit nume este a t a a realizat dinamic, n timpul execuiei. Cu toate astea deniia limbajului evolueaz c tre o rezolutie a numelor a t t a a
1 (N.T. Traducerile celor doi termeni n limba romn sunt improprii, iar nelegerea acestor termeni ar trebui s e mai mult o nelegere a t a t contextual nednd o prea mare importana sensului pe care o are traducerea celor doi termeni). a t

60

Capitol 9. Clase

static , n timpul compil rii. n concluzie nu v bazai prea tare pe varianta dinamic . Deja variabilele locale sunt a a a t a determinate static. O caracteristic a limbajului Python, aste c atribuirile au loc n primul domeniu de vizibilitate(cel mai de jos sau a a cel mai adnc N.T. termenul original este innermost). Atribuirile nu realizeaz o copiere a datelor ci leag nume a a de obiecte. Acest lucru este valabil si pentru stergeri. Instruciunea del x sterge leg tura lui x din domeniul local de t a deniie. De fapt toate operaiile care introduc nume noi au impact asupra domeniului de deniii local: instruciunile t t t t import sau deniia unei funcii introduc numele modulului importat, respectiv numele funciei n domeniul de t t t deniii local. Dac este folosit instrucuinea global se indic intrepretorului ca urm torul nume s e introdus n t a a t a a a domeniul global.

9.3

O prima privire asupra claselor

Noiunea de clase aduce cu sine si cteva alte noiuni noi de sintax , trei tipuri noi de obiecte, si cteva noiuni noi de t t a t semantic . a

9.3.1

Denirea unei clase

Cea mai simpl deniie a unei clase arat astfel: a t a


class ClassName: <statement-1> . . . <statement-N>

Deniiile de clase, la fel ca deniiile de funcii, sunt valabile de abia dup ce sunt executate. Putei insera o deniie t t t a t t de clas n cadrul unei instruciuni if, si clasa nu va exista dect dac condiia instruciunii if va adev rat . a t a t t a a n practic , instruciunile din interiorul unei clase vor deniii de funcii, dar sunt permise si alte instrucuni care pot a t t t t foarte utile uneori. Deniiile de funcii din cadrul unei clase sunt un pic deosebite faa de ce cunoatei, dar despre t t t s t asta vom vorbi mai trziu. Atunci cnd este introdus deniia unei clase noi, un nou domeniu de deniii a numelor este creat si folosit ca a t t domeniu de vizibilitate local, deci toate atribuirile vor afecta noul domeniu de deniii creat. Deniiile de funcii vor t t t introduce numele acelor funcii tot n acest domeniu. t Cnd deniia unei clase se termin normal, f r erori, este creat un obiect nou de tipul class. Pe scurt, acest obiect t a aa conine noul domeniu de deniii creat odat cu deniia clasei. n urm toarea seciune vom discuta mai mult despre t t a t a t obiecte de tip class. Domeniul de vizibilitate existent naintea deniiei clasei este reactivat, si obiectul class este t introdus n respectivul domeniu de deniii sub numele dat de numele specicat n deniia clasei (n exemplul de mai t t sus: ClassName).

9.3.2

Obiecte class

Aceast categorie de obiecte accept dou categorii de operaii: referenieri de atribute si instanieri. a a a t t t Referenierile de atribute folosesc sintaxa standard din Python: obiect.atribut. Atribute valide sunt toate numele t existente n domeniul de deniii n momentul cre rii obiectului class. Aa c , dac deniia clasei arat astfel: t a s a a t a

9.3. O prima privire asupra claselor

61

class MyClass: "Un exemplu simplu de clasa" i = 12345 def f(self): return hello world

Atunci MyClass.i si MyClass.f sunt referine la atribute valabile. Unul dintre atribute este un ntreg (i), iar t cel lalt o metod (f). Se pot realiza atribuiri cu atributele unei clase, deci putei modica valoarea atributului Mya a t Class.i printr-o atribuire. __doc__ este de asemenea un atribut al clasei, care are valoare Un exemplu simplu de clasa. Instanierea claselor folosete notaia de la funcii. Putem s ne imagin m c obiectul clas este o funcie f r t s t t a a a a t aa parametrii care ntoarce ca rezultat o nou instana pentru respectiva clas : Exemplul urm tor: a t a a
x = MyClass()

creeaz o nou instana a clasei si atribuie acest obiect variabilei locale x. a a t Operaia de instaniere creaz un obiect vid. Multe clase prefer s creeze un obiect ntr-o stare iniial . Pentru a t t a a a t a realiza acest lucru o clas trebuie s aib denit o metod special numit __init__() ca n exemplul de mai jos: a a a a a a a
def __init__(self): self.data = []

Atunci cnd o clas are denit metoda __init__(), instanierea respectivei clase apeleaz automat metoda a a t a __init__(). n acest fel se poate obine o instana iniializat a unei anumite clase: t t t a
x = MyClass()

Bineneles metoda __init__() poate avea argumente. n acest caz argumentele primite la instanierea clasei sunt t t transmise automat metodei __init__(). De exemplu:
>>> ... ... ... ... >>> >>> (3, class Complex: def __init__(self, realpart, imagpart): self.r = realpart self.i = imagpart x = Complex( 3.0, -4.5) x.r, x.i 0, 4.5)

V putei gndi la metoda __init__() ca la un constructor, dei nu este un constructor n toat puterea cuvntului. a t s a

9.3.3

Obiecte instaniate t

Ce putem face cu instanele? Singurele operaii acceptate sunt operaiile cu atribute. Exist dou tipuri de nume de t t t a a atribute valide. Prima categorie: propietile sau atribute de tip dat . Aceast categorie corespunde variabilelor instanei n at a a t SmallTalk, si membrilor dat n C++, create automat atunci cnd le sunt atribuite valori. Dac x este o instana a a t a clasei MyClass urm toarea poriune de cod va aa valoarea 16: a t s

62

Capitol 9. Clase

x.counter = 1 while x.counter < 10: x.counter = x.counter * 2 print x.counter del x.counter

A doua categorie sunt metodele. O metod este o funcie ce aparine unui anumit obiect.(n Python termenul de a t t metod nu desemneaz doar o funcie ce aparine instanei numai clase, adic unui obiect; si alte tipuri de obiecte a a t t t a au metode. De exemplu, obiectele list au metodele: append, insert, sort, etc. n cele ce urmeaz vom folosi a a termenul de metod numai n sensul mai sus denit). a Numele de metode disponibile pentru un anumit obiect depind de clasa din care face parte obiectul. Prin deniie, t toate atributele de tip funcie ale unei clase devin metode pentru toate instanele respectivei clase. n exemplul nostru t t x.f este o metod valabil din moment ce MyClass.f este o funcie, n mod contrar, este evident c x.i nu este o a a t a metod . MyClass.i nu este o funcie. Exist o diferena ntre MyClass.f si x.f: prima este un obiect funcie iar a t a t t cea de-a doua un obiect metod (una este funcie, a doua metod ). a t a

9.3.4

Obiecte metoda

n mod uzual o metod este apelat imediat: a a


x.f()

n exemplul nostru aceasta va returna sirul de caractere Hello World!. Oricum nu este neap rat necesar s apel m a a a o metod . Putem face acest lucru mai trziu: a
xf = x.f while 1: print xf()

Exemplul de mai sus va apela Hello World! la innit. Ce se ntmpl exact atunci cnd este apelat o metod ? Ai observat c x.f a fost apelat f r nici un argument, a a a t a a aa chiar dac n deniia funciei era specicat un argument. a t t Ce s-a ntmplat cu argumentul? Cu sigurana Python genereaz o excepie atunci cnd o funcie care necesit un t a t t a argument(dei poate s nu aibe neap rat nevoie de acesta), este apelat f r argumente. s a a a aa Probabil c ai ghicit deja r spunsul: metodele au ntotdeauna ca prim parametru un obiect.n exemplul nostru apelul a t a x.f() este absolut echivalent cu MyClass.f(x). n general a apela o metod cu n parametrii este echivalent cu a a apela funcia corespondent insernd la nceputul listei de n argumente obiectul a c rui metod se dorete apelat . t a a a s a Dac nu ai neles nc cum funcioneaz metodele, o privire asupra implement rii probabil c ar clarica lucrurile. a t t a t a a a Atunci cnd se face o referire la un atribut al unei instane care nu este un atribut dat , clasa din care face parte este t a c utat . Dac numele denot un atribut existent n respectiva clas (deci un obiect de tip funcie), este creat un obiect a a a a a t metod punnd laolalt (mpachetnd) obiectul instana si obiectul funcie(tocmai g sit). n acest fel se creeaza un a a t t a obiect metod . Atunci cnd o metod este apelat cu o list de argumente, obiectul metod este despachetat, o nou a a a a a a list de argumente este construit ad ugnd la nceputul listei de argumente obiectul instana ca prim parametru. n a a a t cele din urm obiectul funcie este apelat cu noua list de argumente. a t a

9.3. O prima privire asupra claselor

63

9.4

Alte observaii t

Atributele dat suprascriu atributele metod cu acelai nume. Pentru a evita conicte de nume ce pot cauza defeciuni a a s t greu de g sit n programe mari, este bine s folosii o convenie pentru denumiri pentru a minimiza sansa apariiei unor a a t t t astfel de conicte. O posibil convenie ar scrierea numelelor de metode cu liter iniial mare, prexarea numelor a t a t a de atribute dat cu un sir de caractere mic si unic, (poate un underscore), sau pentru metode folosii verbe, iar pentru a t propieti substantive. at Propietile pot accesate att de metode, ct si de utilizatorii unui anumit obiect. Cu alte cuvinte clasele nu pot at folosite pentru a implementa tipuri de date abstracte. De fapt, n Python nu exist nici un fel de mecanism de ascundere a a datelor aceasta realizndu-se numai prin convenie. (Pe de alt parte, implementarea limbajului Python, relizat n t a a C, poate ascunde complet detalii de implementare controlnd accesul la datele unui obiect, dac o astfel de abordare a este necesar ). a Utilizatorii unui obiect ar trebui s manipuleze atributele dat (propietaile) cu atenie orice modicare direct a a a t t a acestora putnd duce la o incoerena a obiectului respectiv. De notat este faptul c utilizatorii unui obiect, pot t a ad uga propriile atribute dat f r a afecta n vreun fel metodele, atta timp ct nu apar conicte de nume(i aici a a aa s existena unei convenii v poate scuti de multe nepl ceri). t t a a Nu exist nici o scurt tur pentru referirea atributelor din interiorul unei metode. Acest lucru claric codul unei a a a a metode, nemaiexistnd posibilitatea confuziei ntre variabilele locale si variabilele instanei. t n mod convenional, primul argument al unei metode are numele: self. Aceasta este numai o convenie, numele t t self neavnd nici o semnicaie special n Python.(Folosind aceast convenie codul dumneavoastr va mai uor t a a t a s de citit de c tre programatori). a Orice obiect funcie ca atribut al unei clase denete o metod asociat pentru instanele unei clase. Nu este neap rat t s a a t a necesar ca deniia unei funcii s se ae n cadrul deniiei clasei. n acest sens se poate atribui un obiect funcie unei t t a t t variabile locale. De exemplu:
# Func\c{t}ie definita \^{i}nafara clasei def f1(self, x, y): return min(x, x+y)

class C: f = f1 def g(self): return hello world h = g

Acum f,g, si h sunt toate atribute ale clasei C, si sunt atribute funciei, si n mod consecvent sunt metode pentru toate t instanele clasei C. Aceast practic nu este indicat , ntruct nu face dect s ncurce cititorul programului. t a a a a Metodele pot apela alte metode utiliznd metoda atributelor argumentului self :
class Bag: def empty(self): self.data = [] def add(self, x): self.data.append(x) def addtwice(self, x): self.add(x) self.add(x)

64

Capitol 9. Clase

Metodele pot face referiri la nume globale n acelai mod ca funciile obinuite. Domeniul global de vizibilitate asociat s t s unei metode permite accesul la domeniul de deniie a numelor asociat modului n care se a denit clasa c reia i t a a a aparine metoda. t Clasa n sine nu este folosit niciodat ca un domeniu global de vizibilitate. Pot g site multe utiliz ri ale domeniului a a a a global de vizibilitate, dei unii ar putea considera inutil existena acestuia. s a t

9.5

Mo tenirea s

Nu putem spune despre un limbaj c este orientat obiect, dac sistemul de clase nu pune la dispoziie mecanismul a a t de motenire. Sintaxa pentru motenire (adic pentru crearea deniiei unei clase derivate dintr-o clas de baz ) este s s a t a a urm toarea: a
class DerivedClassName(BaseClassName): <statement-1> . . . <statement-N>

Clasa BaseClassName trebuie s e denit pentru ca deniia clasei derivate s e corect . n loc de un nume de a a t a a clas putei folosi o expresie, acest lucru ind foarte util atunci cnd clasa de baz se a ntr-un alt modul: a t a a
class DerivedClassName(modname.BaseClassName):

Atunci cnd obiectul class pentru clasa derivat , este creat, este memorat si clasa de baz . Acest mecanism este a a a folosit pentru a rezolva referirile la atribute: n caz c un atribut nu este g sit n clasa derivat , este c utat si n clasa a a a a de baz . Regula se aplic recursiv dac clasa de baz este la rndul ei o clas derivat . a a a a a a Instanierea unei clase se face la fel ca pn acum. Dac este apelat o metod a unei instane, numele metodei este t a a a a t c utat nti n deniia clasei derivate, apoi n deniia clasei de baz , si aa mai departe pn cnd este g sit un obiect a t t a s a a funcie corespunz tor n lanul de moteniri. t a t s Clasele derivate pot suprascrie metode ale clasei de baz . Deoarece o metod nu dispune de nici un privilegiu atunci a a cnd apeleaz o alt metod a aceluiai obiect, o metod a clasei de baz care apeleaz o alt metod , denit de a a a s a a a a a a asemenea n clasa de baz , poate s apeleze de fapt o metod suprascris de clasa derivat (pentru programatorii C++ a a a a a putem spune c toate metodele din Python sunt virtuale). a O astfel de metod suprascris poate chiar s extind metoda de baz , n loc de a o nlocui. Exist o cale simpl de a a a a a a a a apela o metod a clasei de baz direct: ClasdeBaz.metod(self.argumente). a a a a a Acest lucru poate foarte util chiar si utilizatorilor(clienilor) unei clase. t

9.5.1

Mo tenirea multipla s

Python pune la dispoziia programatorilor si o form de motenire multipl . O deniie de clas derivat din mai multe t a s a t a a clase de baz arat n felul urm tor: a a a

9.5. Mo tenirea s

65

class DerivedClassName(Base1, Base2, Base3): <statement-1> . . . <statement-N>

Regula dup care sunt c utate atributele este urm toarea: dac un atribut nu este denit n clasa derivat atunci acesta a a a a a este c utat n deniia clasei Base1 si n toate clasele de la care aceasta motenete, apoi este c utat n Base2 si a t s s a n Base3 dup aceleai reguli. Putem rezuma aceast regul n felul urm tor: nti n adncime, si de la stnga la a s a a a dreapta. (Avantajele si dezavantajele acestei reguli pot discutate, ns trebuie s e foarte clar pentru toat lumea a a a c o astfel de regul este absolut necesar , fapt sucient de evident). a a a Este sucient de clar c folosirea mecanismului de motenire multipl va crea mari probleme de ntreinere, deoarece a s a t n Python conictele ce pot ap rea ntre nume sunt evitate numai prin convenii. O problem cunoscut apare atunci a t a a cnd o clas motenete de la dou clase care la rndul lor sunt derivate dintr-o singur clas . Dei este destul de simplu a s s a a a s s ne imagin m ce se va ntmpla n acest caz, nu este clar c regulile vor de folos pentru claricarea situaiei. a a a t

9.6

Variabile private

Exist un suport limitat pentru identicatorii clselor private. Orice identicator de forma __spam (cel puin dou a t a underscore nainte, cel mult un underscore dup ) este acum textual nlocuit cu _cla__spam, unde clas este a a a numele curent al clasei cu underscor-urile din faa suprimate. Mutilarea este realizat fara o analiza a poziiei sintactice t a t a identicatorului, aa nc t putnd folosit la denirea unei instanieri a unei clase private si a variabilelor si s a a t metodelor clasei ca globale, si la memorarea instanierii variabilelor private naceast clas la instanierea altei clase. t a a t O trunchere a numelui poate ap rea cnd acesta este mai lung de 255 de caractere. n afara claselor, sau cnd numele a clasei este alc tuit numai din underscor-uri nu se face eliminarea underscor_urilor. a Acest mecanism pune la dispoziia programatorului o metod foarte facil de a crea atribute private, f r a-i face griji t a a aa s c aceste atribute pot provoca conicte de nume. Toate acestea sunt realizate n Python pentru a preveni eventualele a erori, totui, este n continuare posibil modicarea atributelor private, ceea ce se poate dovedi foarte util n anumite s a cazuri ca de exemplu la depanare. ( Observatie : o clas derivat care are acelai nume cu clasa de baz poate folosi a a s a variabilele private ale clasei de baz ). a Observai c , codul ce este trimis instruciunilor exec, eval() sau evalfile() nu ia n considerare numele t a t clasei care realizeaz invoc rile, acest efect ind similar celui realizat prin instruciuni global, efect ce nu poate a a t obinut pentru cod compilat. Aceeai restricie se aplic si pentru getattr(), setattr() si delattr(), de t s t a asemenea si pentru accesarea direct a dicionarului __dict__. a t Iat un exemplu de clase care implementeaz propriile metode __getattr__() si __setattr__(), si stocheaz a a a toate datele n variabile private:
class VirtualAttributes: __vdict = None __vdict_name = locals().keys()[0] def __init__(self): self.__dict__[self.__vdict_name] = {} def __getattr__(self, name): return self.__vdict[name] def __setattr__(self, name, value): self.__vdict[name] = value

66

Capitol 9. Clase

9.7

Altfel de clase

Cteodat , poate foarte util s putem crea tipuri de date similare celei record din Pascal, sau struct din C, tipuri a a de date care s adune la un loc mai multe date de diferite tipuri. Pentru a realiza acest lucru putei folosi clasele. O a t denire a unei clase vide se poate face astfel :
class Employee: pass

john = Employee() # Se creaz\u{a} o \^{i}nregistrare vid\u{a} de tip employee

# Fill the fields of the record john.name = John Doe john.dept = computer lab john.salary = 1000

S construim un alt scenariu: presupunnd c avei o funcie care prelucreaz anumite date dintr-un obiect ier, putei a a t t a s t s denii o clas cu metodele read() si readline() care s citesc informaii dintr-un sir de caractere n loc de a t a a a t un ier. s Metodele obiectelor au de asemenea atribute: metod.im__self reprezint obiectul de care aparine metoda speca a t icat , iar metod.im__func reprezint funcia corespunz toare metodei. a a a t a

9.7.1

Excepiile pot clase t

Excepiile denite de utilizator pot att obiecte de tip string, ct si clase. Folosind clasele pentru a deni excepii, t t putei crea o ntreag ierarhie de excepii care poate foarte uor extins . t a t s a Exist o alt form a insruciunii raise: a a a t
raise Class, instance raise instance

n prima form instance trebuie s e o instana a clasei Class sau a unei clase derivate. A doua form este o a a t a prescurtare pentru:
raise instance.__class__, instance

O clauz except poate aa att excepii de tip clas , ct si de tip sir de caractere. Urm torul exemplu va aa B, C, a s t a a s D n aceast ordine: a

9.7. Altfel de clase

67

class B: pass class C(B): pass class D(C): pass

for c in [B, C, D]: try: raise c() except D: print "D" except C: print "C" except B: print "B"

De observat c dac ordinea clauzelor except ar fost invers , (cu except B la nceput), exemplul ar aat B, a a a s B, B; deoarece clasa B este clasa din care sunt derivate clasele C si D. Cnd un mesaj de eroare este aat pentru o excepie netratat ce provine dintr-o clas , numele clasei este de asemenea s t a a aat. s

68

Capitol 9. Clase

CAPITOL

ZECE

Continuarea?
S sper m c acest tutorial v-a trezit interesul n ceea ce privete limbajul Python. Ce ar trebui s facei de acum a a a s a t ncolo? Ar trebui s citii, sau cel puin s r sfoii Python Library Reference,document ce explic foarte detaliat ecare funcie, a t t a a t a t tip de date, modul, etc. existent n Python. Distribuia standard de Python conine o cantitate imens de cod scris att t t a n C, ct si n Python, exist module UNIX ce pot folosite pentru a citi c suele de pot electronic , module care a a t sa a faciliteaz lucrul cu protocolul HTTP, module pentru generarea numerelor aleatoare, etc. a Un site foarte util este http://www.python.org. Aici exist documentaii buci de cod scrise de ali programa t at t atori si link-uri legate de Python. Copii ale acestui site exist pe serverele din ntreaga lume (Europa, Australia, Japonia, etc). n funcie de locul n care a t v aai, pentru o vitez de acces mai mare, putei folosi una dintre aceste copii. Un alt site ce se poate dovedi foarte a t a t util este http://starship.python.net. Pentru ntreb ri sau raportarea anumitor probleme putei folosi grupul comp.lang.python, sau putei scrie la Pythona t t list@python.org. n ecare zi sunt puse n jur de 120 de ntreb ri care, de obicei, i g sesc r spunsul. a s a a nainte de a pune o ntrebare, vericai lista ntreb rilor puse frecvent (Freqvently Asked Questions = FAQ) care poate t a g sit la adresa http://www.python.org/doc/faq.html. R spunsurile de la aceast adres , la diferite a a a a a ntreb ri puse de ali programatori, v pot ajuta de foarte multe ori n rezolvarea problemelor dumneavoastr . a t a a

69

70

ANEXA

Editarea n linie de comanda si repetarea comenzilor anterioare


Unele versiuni ale interpretorului Python suport editarea n linie de comand si repetarea unor comenzi anterioare, a a faciliti ntlnite n shell-urile Korn sau GNU Bash. Aceste faciliti sunt implementate folosind biblioteca GNU at at Readline care suport stilurile de editare specice Emacs si Vi. Aceast bibliotec are propria documentaie pe care a a a t nu o vom reproduce aici, ci vom face numai o scurt introducere. a Facilitile despre care v vom vorbi sunt disponibile n versiunile UNIX si CygWin ale interpretorului. at a Acest capitol nu va explica facilitile pachetelor Mark Hammonds Python Win sau IDLE distribuite odat cu Python. at a

A.1 Editarea n linie de comanda


Dac este suportat , aceast facilitate va disponibil atunci cnd interpretorul aeaz promptul principal sau cel a a a a s a secundar. Linia curent poate editat folosind caracterele de control convenionale Emacs. a a t Cele mai importante sunt: C-A(Control-A) mut cursorul la nceputul liniei; a C-E(Control-E) mut cursorul la sfritul liniei; a s C-B mut cursorul cu o poziie la stnga; a t C-F mut cursorul cu o poziie la dreapta; a t BACKSPACE sterge caracterul de la stnga cursorului; C-D sterge caracterul de la dreapta cursorului; C-K sterge tot ce urmez pe linie n dreapta cursorului; a C-Y reface ultimul sir sters cu C-K; C-_ anuleaz ultima comand efectuat . Operaia poate repetat . a a a t a

A.2 Repetarea comenzilor anterioare(History)


Toate comenzile executate sunt salvate ntr-o zon tampon (Buffer). Atunci cnd este executat o nou instruciune a a a t aceasta este salvat la sfritul buffer-ului. a s 71

C-P revine la o comand anterioar n buffer celei executate. a a C-M nainteaz la urm toarea instruciune din buffer. a a t Orice linie din buffer poate modicat . Dac o linie a fost modicat vei vedea un caracter * n faa acesteia care a a a t t ndic c a fost modicat . O instruciune din buffer este executat dac se apas , evident, ENTER. a a a t a a a C-R pornete o c utare incremental n buffer n sens invers. s a a C-S pornete o c utare n sens normal. s a

A.3 Redenirea tastelor funcionale t


Tastele funcionale si ali parametrii ai bibliotecii Readline, pot redenii prin modicarea ierului t t t s /.inputrc. Pentru a redeni funcia unei combinaii de taste trebuie folosit sintaxa: t t a tast:funcie sau ir de caractere:funcie. a t s t O opiune poate setat folosind t a set opiune valoarenou. t a Iat un exemplu: a
# Prefer stil de editare Vi: set editing-mode vi # Editare pe o singura linie: set horizontal-scroll-mode On # Redefinesc cateva taste: Meta-h: backward-kill-word "\C-u": universal-argument "\C-x\C-r": re-read-init-file

n Python principala funcie pentru Tab este aceea de a insera Tab, nu funcia de completare Readline. Dac se t t a dorete ns utilizarea sa n funcia de completare se va pune : s a t
Tab: complete

n /.inputrc. (Bine neles c acum va mai dicil de a scrie spaiile de aliniere) t a t Completarea automat a numelui unei variabile, sau a unui modul, este opional . Pentru a o activa n modul de lucru a t a interactiv ad uga n ierul de startup urm toarele :1 a t s a
import rlcompleter, readline readline.parse_and_bind(tab: complete)

Aceasta leag tasta Tab de funcia de completare, deci ap snd tasta Tab de doua ori activeaz completarea; anala t a a izeaz numele instruciunii Python, variabilele locale curente si numele de module disponibile.Pentru expresiile a t cu punct de tipul string.a, evalueaz expresia pn la nal, dup . si apoi sugereaz completarea dat de a a a a a atributele obiectelor rezultate. De reinut c se poate executa codul unei aplicaii denite dac un obiect ce are metoda t a t a __getattr__() face parte din expresie. Un ier startup mai cuprinz tor poate ar ta ca n exemplul urm tor. De notat c el ii sterge numele pe care le creaz n s a a a a s a momentul n care nu-i mai sunt necesare. Acest lucru se petrece cnd ierul de starup se execut n acelai domeniu de s a s deniie ca si comenzile interactive, iar eliminarea numelor evit generarea unor efecte colaterale n mediul interactiv. t a
1

Python va executa coninutul unui ier identicat prin variabila de mediu PYTHONSTARTUP n momentul pornirii interpretorului interactiv. t s

72

Anexa A. Editarea n linie de comanda si repetarea comenzilor anterioare

Putei g si acest lucru convenabil pentru a p stra cteva module importate, cum ar os, si care se dovedesc necesare t a a n majoritatea sesiunilor interpretorului.
# # # # # # # # # # La interpretorul interactiv Python se adaug\u{a} func\c{t}ia de autocompletare \c{s}i un fi\c{s}ier de tip jurnal pentru comenzi. Se cere Python 2.0+, readline. Autocompletarea este executat\u{a} implicit prin tasta Esc (dar, tasta poate fi \^{i}nlocuit\u{a} -- vezi documenta\c{t}ia readline). Pune\c{t}i fi\c{s}ierul \^{i}n ~/.pystartup, iar variabila de mediu s\u{a}-l indice, cum ar fi \^{i}n bash "export PYTHONSTARTUP=/max/home/itamar/.pystartup". Re\c{t}ine\c{t}i c\u{a} PYTHONSTARTUP nu expandeaz\u{a} "~", deci va trebui indicat\u{a} \^{i}ntraga cale a directorului home . atexit os readline rlcompleter

import import import import

historyPath = os.path.expanduser("~/.pyhistory") def save_history(historyPath=historyPath): import readline readline.write_history_file(historyPath) if os.path.exists(historyPath): readline.read_history_file(historyPath) atexit.register(save_history) del os, atexit, readline, rlcompleter, save_history, historyPath

A.4

Comentarii

Aceste faciliti reprezint un pas enorm comparativ cu versiunile anterioare ale interpretorului; oricum au r mas at a a cteva deziderate nemplinite : ar frumos ca s e sugerat un alineat corect la continuarea unei linii (analizorul a sintactic stie dac se va cere un alineat). Acest nou mecanism ar putea utiliza tabela de simboluri a interpretorului. Util ar si un mecanism care s verice (sau s sugereze) potrivirea parantezelor, ghilimelelor, etc. a a

A.4. Comentarii

73

74

ANEXA

Aritmetica n virgula otanta: rezultate si limitari


Numerele n virgul otant sunt reprezentate n hardware-ul calculatorului ca fracii n baza 2 (binare). De exemplu, a a t fracia zecimal t a
0.125

are valoarea 1/10 + 2/100 + 5/1000, si n acelai fel fracia binar s t a


0.001

are valoarea 0/2 + 0/4 + 1/8. Aceste dou fracii au aceeai valoare, singura diferena real ind c prima este scris a t s t a a a n baza 10, iar a doua n baza 2. Din p cate majoritatea fraciilor zecimale nu pot reprezentate corect ca fracii a t t binare. O prim concluzie este c , (n general, numerele n virgul otant zecimal pe care le introducei au numai o a a a a a t reprezentare aproximativ prin numerele n virgul otant binar memorate n calculator. a a a a Problema este uor de neles nt n baza 10. S consider m fracia 1/3. O pute aproxima cu o fracie baza 10: s t a a t t t
0.3

sau, mai precis,


0.33

sau ,i mai precis, s


0.333

si tot aa. Nu conteaz ce num r de digii vei scrie, rezultatul nu va nicicd exact 1/3, dar crete acurateea aprox s a a t t s t im rii lui 1/3. a n acelai mod, nu conteaz cti digii n baza 2 folosii, valoarea zecimal 0.1 nu va reprezentat exact niciodat s a t t a a a printr-o fracie. n baza 2, 1/10 este o fracie care se repet la innit t t a
0.0001100110011001100110011001100110011001100110011...

Oprirea la un num r nit de bii d o aproximare. Iat ce se aeaz n situaia urm toare : a t a a s a t a

75

>>> 0.1 0.10000000000000001

Pe majoritatea mainilor existente ast zi acest rezultat se aeaz dac introducei 0.1 la prompterului Python-ului. s a s a a t Se ntmpl aa pentru c num rul de bii utilizai de hardware s mememoreze valoarea n virgul otant variaz a s a a t t a a a a de la o main la alta, iar Python listeaz doar o aproximaie zecimal a valorii zecimale reale a aproximaiei binare s a a t a t memorat n main . Pe majoritatea mainilor, dac Python va tip ri valoarea zecimal real a aproximaiei binare a s a s a a a a t memorate pentru 0.1, va aa s
>>> 0.1 0.1000000000000000055511151231257827021181583404541015625

Prompterul Python utilizeaz funcia implicit repr() ca s obin o versiune de sir pentru toate obiectele pe care le a t a a t a aeaz . n cazul numerele otante repr(oat) rotunjete valoarea zecimal la 17 digii semnicativi, astfel s a s a t
0.10000000000000001

repr(oat) folosete 17 bii semnicativi pentru c sunt considerai sucieni pe majoritatea mainilor, aa c relaia s t a t t s s a t eval(repr(x)) == x este exact pentru toate numerele otante nite x, dar rotunjirea la 16 bii nu este sucient a t a pentru a face relaia adev rat . t a a Acesta este un lucru normal al aritmeticii binare n virgul otant : nu este un bug Python, nici un bug al codului a a dumneavoastr si vei constata o astfel de anomalie n toate limbajele care folosesc aritmetica n virgul otant oferit a t a a a de hardware (unele limbaje pot s nu aeze implicit diferena) a s t Funcia intern Python str() genereaz numai 12 digii semnicativi si poate c dorii s o folosii modicat . Este t a a t a t a t a des utilizat funcia eval(str(x)) pentru a-l obine pe x, dar este mai placut s se aeze : a t t a s
>>> print str(0.1) 0.1

E bine de stiut c , n sens real, este o iluzie : n main valoarea nu este exact 1/10, valoarea adev rat din main este a s a a a s a rotunjit la aare. a s Aceast surpriz este urmata de altele. De exemplu dup ce se aeaz a a a s a
>>> 0.1 0.10000000000000001

apare tentaia s utilizai funcia round() ca s trunchiai iar si la un digit. Dar aceasta nu face nimic: t a t t a t a
>>> round(0.1, 1) 0.10000000000000001

Problema este c valoarea memorat nvirgul otant binar pentru "0.1" a fost f cut n cea mai bun aproximare a a a a a a a a binar posibil la 1/10, deci orice alt rotunjire ulterioar nu o poate face mai bine : a fost dat deja cea mai bun a a a a a a soluie. t Alt consecina a faptului c 0.1 nu este exact 1/10 este aceea c ad ugnd la 0.1 pe el nsui de 10 ori nu se obine a t a a a s t 1.0:

76

Anexa B. Aritmetica n virgula otanta: rezultate si limitari

>>> sum = 0.0 >>> for i in range(10): ... sum += 0.1 ... fs>>> sum 0.99999999999999989

Aritmetica binar n virgul otant are multe surprize de acest gen. Problema cu "0.1" este explicat n seciunea a a a a t urm toare, "Erori de reprezentare". Vezi : The Perils of Floating Point privind tratarea complet a altor surprize de a a acest gen. Cum s-ar spune la sfrit: "nu este uor de r spuns". Totui nu disperai din cauza rgulei otante! Erorile operaiilor s s a s t t de otant din Python sunt motenite de la virgula otant a hardware-ului si la majoritatea mainilor sunt de un ordin a s a s mai mic de 1/2**53 pe operaie. Acestea sunt mai mult dect acceptabile pentru cele mai multe aplicaii, dar trebuie t t s reinei c nu sunt datorate aritmeticii zecimale si c la ecare operaie nvirgul otant apare o eroare de rotunjire. a t t a a t a a Pn la apariia unor cazuri patologice, pentru cele mai multe situaii de utilizare a aritmeticii nvirgul otant se a t t a a obin rezultatele ateptate, dac pur si simplu se rotunjete rezultatul nal aat la num rul de zecimale dorit. Uzual t s a s s a funcia str() este sucient , iar pentru un control mai riguros a se vedea discuia despre operatorul de format % : t a t formatele %g, %f si %e sunt moduri exibile si uoare pentru aarea rezultatelor. s s

B.1

Erori de reprezentare

Seciunea explic ndetaliu exemplul "0.1" si arat cum se poate face o analiz exact a cazurilor. n principal se t a a a a urm rete familiarizarea cu reprezentarea binar n virgul oant . a s a a a Eroarea de reprezentare se refer la faptul c fraciile zecimale nu se pot reprezenta exact ca fracii binare (n baza a a t t 2). Acesta este motivul major pentru care Python (sau Perl, C, C++,Java, Fortran, si multe altele) nu aeaz valoarea s a exact a num rului zecimal pe care-l ateptai : a a s t
>>> 0.1 0.10000000000000001

Ce este asta? 1/10 nu este reprezentat exact ca o fracie binar . Cele mai multe maini utilizeaz ast zi (noiembrie t a s a a 2000) aritmetica de virgul otant IEEE-754 si cele mai multe platforme mapeaz otantele Python n"dubl precizie" a a a a IEEE-754. Dublele 754 au 53 bii de precizie. Aa c la intrarea n calculator se chinuie s converteasc 0.1 ncea mai t s a a a apropiat fracie posibil de forma J/2**N, unde J este un ntreg de exact 53 de bii. Se rescrie a t a t
1 / 10 ~= J / (2**N)

ca
J ~= 2**N / 10

si reapelnd J are exact 53 de bii (este >= 2**52 dar < 2**53), si cea mai bun valoare pentru N este 56: t a

B.1. Erori de reprezentare

77

>>> 2L**52 4503599627370496L >>> 2L**53 9007199254740992L >>> 2L**56/10 7205759403792793L

Asta este, 56 este singura valoare pentru N care las J cu exact 53 de bii. Atunci cea mai bun valoare posibil pentru a t a a J este ctul rotunjit:
>>> q, r = divmod(2L**56, 10) >>> r 6L

Dup ce restul este mai mare dect jum tatea lui 10, cea mai bun aproximaie se obine prin rotunjirea: a a a t t
>>> q+1 7205759403792794L

Astfel cea mai bun aproximaie a lui 1/10, n dubla precizie 754, este peste 2**56, sau a t
7205759403792794 / 72057594037927936

De remarcat c pn la rotunjire, valoarea este de fapt un pic mai mare dect 1/10; dac nu am rotunji ctul va un a a a pic mai mic dect 1/10. Dar n nici un caz nu poate exact 1/10! Deci, niciodata computerul nu va ar ta 1/10: ce va ar ta este exact fracia dat mai jos, cea mai bun aproximaie n a a t a a t 754 care poate dat : a
>>> .1 * 2L**56 7205759403792794.0

Dac se nmulete fracia cu 10**30, vom vedea valoarea (truncheat ) a celor mai semnicativi 30 de digii zecimali a t s t a t ai s i: a
>>> 7205759403792794L * 10L**30 / 2L**56 100000000000000005551115123125L

nsemnnd c num rul exact memorat n calculator este aproximativ egal cu valoarea zecimal a a a 0.100000000000000005551115123125. Rotunjind la 17 digii semnicativi rezult 0.100000000000000001 pe t a care Python l aeaz (va aa pe orice platform conform 754 care va face tot posibilul s converteasc intrare si s a s a a a a ieire prin biblioteca C proprie al dumneavoastr s-ar putea s nu reueasc acest lucru!) s a a s a

78

Anexa B. Aritmetica n virgula otanta: rezultate si limitari

ANEXA

Istoria si licena t
C.1 Istoricul produsului Python

Python a fost creat la nceputul anilor 1990 de c tre Guido van Rossum la Stichting Mathematisch Centrum (CWI, vezi a http://www.cwi.nl/) din Olanda, ca succesor al limbajului ABC. Guido a r mas principalul autor al Pythona ului, care acumuleaz multe contribuii ale altora. a t n 1995 Guido ii continu munca la Python la Corporation for National Research Initiatives (CNRI, vezi http: s a //www.cnri.reston.va.us/) n Reston, Virginia, unde a lansat cteva versiuni ale software-ului. n mai 2000, Guido si echipa de dezvoltare a Python-ului s-a mutat la BeOpen.com, unde a format echipa BeOpen PythonLabs. octombrie 2000, colectivul PythonLabs s-a mutat la Digital Creations (vezi http:// www.digicool.com/).n 2001 ia natere Python Software Foundation (PSF, vezi http://www.python.org/ s psf/) o organizaie non prot creat special pentru a dene drepturile de autor1 referitoare la Python. Digital Creations t a t este unul din sponsorii PSF. Toate lans rile2 Python sunt Open Source (vezi http://www.opensource.org/ pentru a g si deniia Open a a t Source ). Istoricete vorbind cele mai multe dintre lans rile Python, nu toate, sunt de asemenea compatibile s a GPL(General Public License). Tabelul urm tor face un sumar al diferitelor lans ri. a a Release 0.9.0 thru 1.2 1.3 thru 1.5.2 1.6 2.0 1.6.1 2.1 2.0.1 2.1.1 2.2 Derived from n/a 1.2 1.5.2 1.6 1.6 2.0+1.6.1 2.0+1.6.1 2.1+2.0.1 2.1.1 Year 1991-1995 1995-1999 2000 2000 2001 2001 2001 2001 2001 Owner CWI CNRI CNRI BeOpen.com CNRI PSF PSF PSF PSF GPL compatible? yes yes no no no no yes yes yes

Not : Compatibil GPL nu nseamn c Python este distribuit sub GPL. Toate licenele Python, spre deosebire de GPL, a a a t ii permit s distribui o versiune modicat f r a-i face si modic rile open source. Licenele compatibile GPL fac t a a aa t a t posibil combinarea Pyton-ului cu alte software care au ap rut sub GPL; celelate neputnd face acest lucru. a a Mulumim acelor voluntari numeroi din exteriorul echipei, care lucrnd sub coordonarea lui Guido au f cut posibile t s a aceste lans i. a
1 Intellectual 2 N.T.

Property = termenul de lansaree g sit nanex este traducerea termenului englezesc release a a

79

C.2

Terms and conditions for accessing or otherwise using Python


PSF LICENSE AGREEMENT FOR PYTHON 2.2

1. This LICENSE AGREEMENT is between the Python Software Foundation (PSF), and the Individual or Organization (Licensee) accessing and otherwise using Python 2.2 software in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 2.2 alone or in any derivative version, provided, however, that PSFs License Agreement and PSFs notice of copyright, i.e., Copyright c 2001 Python Software Foundation; All Rights Reserved are retained in Python 2.2 alone or in any derivative version prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on or incorporates Python 2.2 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python 2.2. 4. PSF is making Python 2.2 available to Licensee on an AS IS basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.2 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 2.2 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.2, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between PSF and Licensee. This License Agreement does not grant permission to use PSF trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 8. By copying, installing or otherwise using Python 2.2, Licensee agrees to be bound by the terms and conditions of this License Agreement. BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 1. This LICENSE AGREEMENT is between BeOpen.com (BeOpen), having an ofce at 160 Saratoga Avenue, Santa Clara, CA 95051, and the Individual or Organization (Licensee) accessing and otherwise using this software in source or binary form and its associated documentation (the Software). 2. Subject to the terms and conditions of this BeOpen Python License Agreement, BeOpen hereby grants Licensee a non-exclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use the Software alone or in any derivative version, provided, however, that the BeOpen Python License is retained in the Software, alone or in any derivative version prepared by Licensee. 3. BeOpen is making the Software available to Licensee on an AS IS basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.

80

Anexa C. Istoria si licena t

4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 5. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 6. This License Agreement shall be governed by and interpreted in all respects by the law of the State of California, excluding conict of law provisions. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between BeOpen and Licensee. This License Agreement does not grant permission to use BeOpen trademarks or trade names in a trademark sense to endorse or promote products or services of Licensee, or any third party. As an exception, the BeOpen Python logos available at http://www.pythonlabs.com/logos.html may be used according to the permissions granted on that web page. 7. By copying, installing or otherwise using the software, Licensee agrees to be bound by the terms and conditions of this License Agreement. CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 1. This LICENSE AGREEMENT is between the Corporation for National Research Initiatives, having an ofce at 1895 Preston White Drive, Reston, VA 20191 (CNRI), and the Individual or Organization (Licensee) accessing and otherwise using Python 1.6.1 software in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, CNRI hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 1.6.1 alone or in any derivative version, provided, however, that CNRIs License Agreement and CNRIs notice of copyright, i.e., Copyright c 1995-2001 Corporation for National Research Initiatives; All Rights Reserved are retained in Python 1.6.1 alone or in any derivative version prepared by Licensee. Alternately, in lieu of CNRIs License Agreement, Licensee may substitute the following text (omitting the quotes): Python 1.6.1 is made available subject to the terms and conditions in CNRIs License Agreement. This Agreement together with Python 1.6.1 may be located on the Internet using the following unique, persistent identier (known as a handle): 1895.22/1013. This Agreement may also be obtained from a proxy server on the Internet using the following URL: http://hdl.handle.net/1895. 22/1013. 3. In the event Licensee prepares a derivative work that is based on or incorporates Python 1.6.1 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python 1.6.1. 4. CNRI is making Python 1.6.1 available to Licensee on an AS IS basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 7. This License Agreement shall be governed by the federal intellectual property law of the United States, including without limitation the federal copyright law, and, to the extent such U.S. federal law does not apply, by the law of the Commonwealth of Virginia, excluding Virginias conict of law provisions. Notwithstanding the foregoing, with regard to derivative works based on Python 1.6.1 that incorporate non-separable material that was previously distributed under the GNU General Public License (GPL), the law of the Commonwealth of C.2. Terms and conditions for accessing or otherwise using Python 81

Virginia shall govern this License Agreement only as to issues arising under or with respect to Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between CNRI and Licensee. This License Agreement does not grant permission to use CNRI trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 8. By clicking on the ACCEPT button where indicated, or by copying, installing or otherwise using Python 1.6.1, Licensee agrees to be bound by the terms and conditions of this License Agreement. ACCEPT CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 Copyright c 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, The Netherlands. All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Stichting Mathematisch Centrum or CWI not be used in advertising or publicity pertaining to distribution of the software without specic, written prior permission. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

82

Anexa C. Istoria si licena t