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 s i u sor de nv a tat. Are structuri de date de nivel nalt, eciente s i o simpl a dar ecient a abordare a program arii orientate pe obiect. Sintaxa elegant as i natura sa interpretat a, fac din Python un limbaj ideal pentru elaborarea de script-uri s i dezvoltarea rapid a de aplica tii n multe domenii, pe majoritatea platformelor. Interpretorul Python s i libr aria standard sunt oferite sub form a de surse sau compilate pentru majoritatea platformelor existente, pe site-ul Python, http://www.python.org/, s i pot distribuite gratuit. Pe acela si site pute ti g asi distribu tii Python s i module scrise de al ti programatori, precum s i documenta tie adi tional a. Interpretorul Python este u sor de extins prin ad augarea de noi func tii s i tipuri de date implementate n C sau C++ (sau alte limbaje apelabile din C). Python poate folosit s i drept limbaj de extensie pentru aplica tii. Acest material informeaz a cititorul despre conceptele de baz as i capabilit a tile sistemului s i limbajului Python. Ar de preferat s a ave ti la ndemn a un interpretor Python pentru a experimenta, dar toate exemplele cuprinse n acest material pot n telese f ar a a imperativ a prezen ta interpretorului. Pentru o descriere a obiectelor s i modulelor standard, consulta ti documentul Python Library Reference. Documentul Python Reference Manual d a o deni tie mai exact a a limbajului. Dac a dori ti s a extinde ti sau s a implementa ti limbajul Python ntr-o aplica tie cu ajutorul C++ consulta ti documentul Extending and Embedding the Python Interpreter s i Python/C API Reference. Exist as i c ar ti care acoper a limbajul Python n toat a complexitatea sa. Acest tutorial nu ncearc a s a acopere toate facilit a tile Python-ului, sau m acar cele mai folosite dintre ele. n schimb, v a prezint a cele mai interesante s i importante facilit a ti, s i v a va da o idee despre modul de func tionare al limbajului. Dup a ce ve ti citi acest tutorial, ve ti putea citi s i scrie module sau programe Python, s i ve ti preg ati ti s a v a ta ti mai multe despre diferitele libr arii incluse n distribu tia Python, descrise n documentul Python Library Reference.

CUPRINS

1 2

De ce Python? 1.1 n continuare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Utilizarea interpretorului Python 2.1 Invocarea interpretorului . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Interpretorul s i mediul n care ruleaz a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . O introducere scurt a n Python 3.1 Utilizarea Python-ului drept calculator de birou . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Primii pa si n programare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Structuri de control 4.1 Instruc tiuni if . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Instruc tiuni for . . . . . . . . . . . . . . . . . . . . . . . . . 4.3 Func tia range() . . . . . . . . . . . . . . . . . . . . . . . . 4.4 Instruc tiuni break s i continue, s i clauze else pentru bucle 4.5 Instruc tiuni pass . . . . . . . . . . . . . . . . . . . . . . . . 4.6 Func tii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.7 Mai multe despre func tii . . . . . . . . . . . . . . . . . . . . . Strucuri de date 5.1 Mai multe despre liste . . 5.2 Instruc tiunea del . . . . 5.3 Perechi s i secven te . . . . 5.4 Dic tionare . . . . . . . . 5.5 Mai multe despre condi tii 5.6 Compararea secven telor . Module 6.1 Mai multe despre module 6.2 Module standard . . . . . 6.3 Func tia dir() . . . . . 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 ari s i ie siri 7.1 Formatarea mai elegant a a datelor la ie sire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.2 Fi siere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Erori s i excep tii 8.1 Erori de sintax a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8.2 8.3 8.4 8.5 8.6 9

Excep tii . . . . . . . . . . . . Tratarea excep tiilor . . . . . . Generarea excep tiilor . . . . . Excep tii denite de utilizator . Denirea ac tiunilor de cur a tare

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

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

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

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

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

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

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

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

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

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

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) s i domenii de deni tie a numelor(Name Spaces) 9.3 O prim a privire asupra claselor . . . . . . . . . . . . . . . . . . . . . . . . . . 9.4 Alte observa tii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.5 Mo stenirea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.6 Variabile private . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.7 Altfel de clase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

10 Continuarea? A Editarea n linie de comand as i repetarea comenzilor anterioare A.1 Editarea n linie de comand a . . . . . . . . . . . . . . . . . A.2 Repetarea comenzilor anterioare(History) . . . . . . . . . . A.3 Redenirea tastelor func tionale . . . . . . . . . . . . . . . . A.4 Comentarii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

71 71 71 72 73 75 77 79 79 80

B Aritmetica n virgul a otant a: rezultate s i limit ari B.1 Erori de reprezentare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C Istoria s i licen ta C.1 Istoricul produsului Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.2 Terms and conditions for accessing or otherwise using Python . . . . . . . . . . . . . . . . . . . . .

ii

CAPITOL

UNU

De ce Python?
Dac a a ti construit vreodat a un shell complex, probabil cunoa ste ti senza tia: vre ti s a ad auga ti nc a o facilitate, dar este deja att de lent, att de mare, att de complicat; sau ad augarea facilit a tii implic a un apel de func tie de sistem, sau alt a func tie care nu este accesibil a dec at din C. De obicei problema pe care o ave ti de rezolvat nu este sucient de serioas a astfel nct s a merite s a rescrie ti shell-ul n C; poate c a rezolvarea problemei necesit a folosirea s ir-urilor de lungime variabil a, sau a listelor sortate de nume de siere, lucruri accesibile ntr-un shell, dar care necesit a mult a munc a pentru a implementate n C; sau poate c a nu sunte ti sucient de familiarizat cu limbajul C. S a consider am o alt a situa tie: presupunem c a trebuie s a lucra ti cu anumite biblioteci C, s i ciclul obi snuit de scrierecompilare-testare-recompilare este prea lent. Vre ti s a dezvolta ti mult mai rapid software. E posibil s a scris un program care poate folosi un limbaj de extensie, s i nu vre ti s a dezvolta ti un alt limbaj pentru asta, s a scrie ti s i s a verica ti de erori un interpretor pentru acest limbaj, pentru ca apoi s a-l ad auga ti la aplica tia dumneavoastr a. n aceste cazuri Python este limbajul de care ave ti nevoie. Este simplu de folosit, dar este un limbaj de programare adev arat, oferind posibilitatea unei mai bune structur ari, s i un suport mai bun pentru programe mari dect ofer a un shell. Pe de alt a parte dispune de o mult mai bun a vericare a erorilor dect C-ul, s i ind un limbaj de nivel foarte nalt, dispune de tipuri de date de nivel nalt cum ar tablouri sau dic tionare foarte exibile, a c aror implementare n C ar lua programatorului zile. Datorit a caracterului general al tipurilor de date Python poate aplicat ntr-o arie mult mai larg a de probleme dect AWK sau PERL. Cu toate astea, multe lucruri se realizeaz a la fel de u sor n Python ca s i n aceste limbaje. Python permite divizarea programelor dumneavoastr a n module care pot folosite apoi n alte programe Python. Dispune de o colec tie vast a de module standard de la care pute ti porni n construirea programului dumneavoastr a, sau pentru a nv a ta programarea n Python. Exist a de asemenea module ncorporate care ofer a facilit a ti pentru sistemul de intr ari ie siri (I/O), apeluri de sistem, sockets, s i chiar interfe te pentru sisteme de interfa tare grac a utilizator (GUI) precum TK. Python este un limbaj interpretat, care v a poate accelera munca n timpul procesului de dezvoltare, ne mai ind nevoit s a compila ti codul de ecare dat a. Interpretorul poate folosit interactiv, ceea ce v a permite s a testa ti foarte u sor anumite facilit a ti ale limbajului, s a scrie ti imediat programe dispensabile, sau s a testa ti anumite func tii nainte de a le folosi n programul dumneavoastr a. Este foarte folositor s i drept, calculator de birou. Python permite scrierea unor programe foarte compacte s i u sor de citit. Programele scrise n Python sunt mult mai mici decat echivalentele n C sau C++ pentru c a: tipurile de date de nivel nalt v a permit s a realiza ti opera tii complexe ntr-o singur a instruc tiune; gruparea instruc tiunilor este dat a de paragrafare n loc de blocuri begin/end sau de acolade; nu este necesar a declararea variabilelor. Python este extensibil: dac a ave ti cuno stin te de C pute ti foarte u sor sa ad auga ti o nou a func tie sau un modul, e pentru a efectua opera tii la vitez a maxim a, e pentru a lega programe Python la biblioteci disponibile numai n form a binar a (biblioteci grace). Pute ti de exemplu s a ad auga ti interpretorul Python ntr-o aplica tie C s i s a l folosi ti ca un limbaj de comand a sau de extensie pentru acea aplica tie. 1

Numele limbajului provine de la emisiunea BBC Monthy Pythons Flying Circus (Circul zbur ator al s arpelui Monty) s i nu are nici o leg atur a cu disgra tioasele reptile. Referin te la Monty Python n documenta tia ce urmeaz a nu numai c a sunt permise, sunt chiar ncurajate!

1.1

n continuare

Acum c a ave ti o idee despre Python, poate dori ti s a l examina ti mai n detaliu. Din moment ce, cea mai bun a metod a de a nva ta un limbaj de programare este utilizarea acestuia, sunte ti s i dumneavoastr a invita ti s a o face ti. n urmatorul capitol este explicat a utilizarea interpretorului. Informa tiile ce urmeaz a pot p area banale, dar sunt esen tiale pentru testarea exemplelor ce vor urma. Cealalt a parte a tutorialului prezint a diferite facilita ti ale limbajului Python. Aceast a prezentare este bogat a n exemple, ncepnd cu expresii simple, instruc tiuni, tipuri de date s i terminnd cu func tii, module s i concepte avansate cum ar tratarea excep tiilor s i clase denite de utilizator.

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 ma sinile unde exist a aceast a cale. n lista cu directoarele de sistem a U NIX introduce ti calea /usr/local/bin pentru a putea porni interpretorul cu comanda :
python

Din moment ce directorul n care este instalat interpretorul, poate modicat la instalare, s i alte c ai sunt posibile. Vorbi ti cu administratorul dumneavoastr a de sistem nainte de a lua o decizie n privin ta directorului de instalare. (Ex: /usr/local/python este o alternativ a foarte popular a). Tastarea unui caracter de sfr sit de sier (Control-D pe U NIX, sau Control-Z pe DOS sau Windows) n timpul prompt-ului principal determin a oprirea execu tiei interpretorului cu cod de ie sire zero. Dac a acest lucru nu func tioneaz a ncerca ti comenzile: import sys; sys.exit(). Facilit a tile de editare n linie de comand a ale interpretorului nu sunt deloc deosebite. Pe sisteme U NIX, n timpul instal arii Python, pute ti activa op tiunea de suport a bibliotecii GNU de editare n linie de comand a, care adaug a mai multe facilit a ti pentru editare n linie de comand a. Pentru a vedea dac a aceast a op tiune este activat a, tasta ti combina tia de taste Control-P la primul prompt Python. Dac a auzi ti un sunet, ave ti activat a op tiunea despre care vorbeam mai sus (consulta ti Anexa A, pentru o scurt a list a de combina tii de taste foarte utile). Dac a nu se ntampl a nimic sau este a sat ^P, op tiunea de editare a liniei de comand a nu este activat a, deci nu ve ti putea dect s as terge ti (BACKSPACE) sau s a introduce ti noi caractere n linie. Interpretorul func tioneaz a aseman ator shell-ului U NIX: Cnd este apelat cu intrarea standard conectat a la un dispozitiv TTY, cite ste s i execut a comenzi interactiv. Cnd este apelat cu un parametru reprezentnd un nume de sier, cite ste s i execut a un script (program) din acel sier. O a treia modalitate de a porni interpretorul este python -c command[arg] . . . care execut a instruc tiunea/instruc tiunile din comand a, analog op tiunii -c a shell-ului. Din moment ce o comand a poate con tine spa tii sau alte caractere utilizate de shell (ca separatori de parametrii de exemplu) este bine s a introduce ti comanda/comenzile ntre ghilimele. ntre python file s Observa ti c a exist a o diferen ta i python <file. n primul caz, datele de intrare ale programului sunt oferite de sier. Din moment ce acest sier a fost deja citit pan a la cap at nainte de nceperea programului, programul va ntlni sfr sit de sier imediat. n al doilea caz (cel mai interesant s i folosit) datele de intrare sunt oferite de orice sier sau dispozitiv conectat la intrarea standard a interpretorului Python. Cnd este rulat un script, este cteodat a folositor ca dup a rularea script-ului s a se intre n modul interactiv. Acest lucru se realizeaz a foarte simplu folosind un parametru -i nainte de numele sierului n care se a a script-ul. Evident c a acest parametru nu va func tiona dac a script-ul este citit de la intrarea standard.

2.1.1

Transmiterea argumentelor

Atunci cnd dup a parametrul care reprezint a sierul n care se a a script-ul, interpretorului i se mai transmit s i al ti parametrii, acesta i va transmite mai departe script-ului prin intermediul variabilei sys.argv, variabil a ce con tine o list a (vector) de s iruri de caractere. Atunci cnd n loc de numele sierului se transmite _ (adic a intrarea standard), sys.argv[0] = _. Cnd este folosit a comanda -c, sys.argv[0] = -c. Parametrii de dup a -c comand a nu sunt considera ti parametrii ai interpretorului, ci sunt scri si n sys.argv pentru a folosi ti de comand a.

2.1.2

Modul interactiv

Cnd comenzile sunt citite de la un TTY, se spune c a interpretorul se a a n modul interactiv. n acest mod exist a dou a prompt-uri. Prompt-ul principal (de obicei >>> ) s i promptul secundar (de obicei ... ) folosit pentru continuarea liniilor. Interpretorul a seaz a imediat dup a pornire un mesaj de ntmpinare ncare se specic a versiunea s i 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 construc tii multilinie. De exemplu:
>>> pamantul_este_plat = 1 >>> if pamantul_este_plat: ... print "Ai grija sa nu cazi!" ... Ai grija sa nu cazi!

2.2 Interpretorul s i mediul n care ruleaza


2.2.1 Tratarea erorilor

Cand are loc o eroare, interpretorul a seaz a un mesaj de eroare s i starea stivei n momentul respectiv. n modul interactiv revine la prompt-ul principal. Atunci cnd intr arile provin dintr-un sier, interpretorul se opre ste cu un cod de eroare diferit de zero dup a ce a a sat starea stivei.(Excep tiile tratate nu sunt erori n acest context). Unele erori sunt inevitabil fatale s i cauzeaz a terminarea anormal a cu cod de ie sire diferit de zero (Ex: lipsa de memorie). Toate mesajele de eroare sunt scrise la ie sirea pentru erori (standard error stream). Ie sirile provenite din execu tia comenzilor sunt scrise la ie sirea standard. Dac a se apas a caracterul de ntrerupere (Control-C, DEL) n primul prompt sau n cel secundar, comanda scris a este pierdut a revenindu-se la promptul principal. ntreruperea unei comenzi n timpul execu tiei creeaz a o excep tie de tip Keyboard Interrupt, care poate tratat a ntr-o instruc tiune try.

2.2.2

Script-uri Python Executabile

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

Capitol 2. Utilizarea interpretorului Python

(presupunem c a interpretorul se a a n variabila de sistem PATH a utilizatorului) la nceputul script-ului s i apoi transformnd sierul n executabil. Caracterele #! trebuie s a e neap arat primele dou a caractere din sier. Observa tie: Caracterul # este folosit pentru comentarii n Python.

2.2.3

Fi sierul de ini tializare al modului interactiv

Cnd folosi ti Python n modul interactiv, poate foarte folositor s a ave ti cteva comenzi care s a se execute automat de ecare dat a cnd este pornit interpretorul. Pute ti realiza acest lucru crend o variabil a de sistem cu numele PYTHONSTARTUP care s a con tin a numele unui sier n care s a ave ti comenzile, care dori ti s a e executate la pornirea interpretorului. Aceast a procedur a este similar a, facilit a tii .prole de pe sistemele U NIX. Acest sier de ini tializare este interpretat numai cnd este pornit interpretorul Python n mod interactiv. Fi sierul nu este interpretat nici cnd interpretorul Python are ca intrare un sier, nici cnd sursa explicit a a comenzilor este /dev/tty. Acest sier este executat n acela si cadru n care se execut as i comenzile interactive. n acest sier pot schimbate chiar s i prompt-urile sys.ps1 sau sys.ps2. Dac a dori ti s a executa ti s i alte siere de ini tializare, din directorul curent trebuie s a ad auga ti cteva linii la sierul principal de ini tializare, utiliznd un cod ca acesta if os.path.isfile(.pythonrc.py) : execfile(.pythonrc.py) Dac a dori ti s a folosi ti acest sier de ini tializare, ntr-un program, trebuie s a specica ti acest lucru explicit n cadrul programului astfel:
import os filename = os.environ.get(PYTHONSTARTUP) if filename and os.path.isfile(filename): execfile(filename)

2.2. Interpretorul s i mediul n care ruleaza

CAPITOL

TREI

n Python O introducere scurta


n exemplele ce urmeaz a, intr arile s i ie sirile vor deosebite prin prezen ta sau absen ta prompt-urilor (principal >>> sau secundar ... ). Pentru a testa un exemplu trebuie s a scrie ti linia ce apare imediat dup a prompt. Liniile care nu sunt linii de ie au caracterele >>> sau ... n fa ta sire, rezultate n urma comenzilor anterioare, sau a ultimei comenzi. Un prompt secundar, f ar a nimic dup a el, nseamn a c a trebuie s a introduce ti o linie goal a. Acest procedeu este folosit pentru terminarea unui bloc de instruc tiuni (de tipul begin...end;{...}). Multe din exemplele din acest tutorial con tin comentarii. n Python comentariile ncep cu un caracter # s i se termin a la sfr situl liniei. Un comentariu poate ap area la sfr situl unei linii, dar nu poate ap area n cadrul unui string. Un caracter # n cadrul unui string nu reprezint a nceputul unui comentariu ci doar un caracter #. Iat a cteva exemple:
# 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 a ncerc am cteva comenzi simple Python. Porni ti interpretorul s i a stepta ti s a apar a prompt-ul principal >>> .(Nu ar trebui s a dureze prea mult).

3.1.1

Numere

Interpretorul func tioneaz a ca un simplu calculator: pute ti scrie o expresie, s i ca r aspuns ve ti primi rezultatul. Ordinea opera tiilor s i modul de parantezare sunt la fel ca n majoritatea limbajelor (ex: Pascal sau C). 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 a nu constituie o ie sire (nu este tip arit a pe ecran):
>>> latime = 20 >>> inaltime = 5*9 >>> latime * inaltime 900

O valoare poate atribuit a simultan mai multor variabile:


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

Exist a suport complet pentru virgul a mobil a. Operatorii care au operanzi de tipuri diferite vor converti operandul ntreg n virgul a mobil 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 a diferit a de zero au forma (real+imagj) sau pot create folosind func tia complex(real, imag):

n Python Capitol 3. O introducere scurta

>>> 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 a numere reale n virgul a mobil a: partea real as i cea imaginar a. Pentru a aa partea real a sau cea imaginar a dintr-un num ar complex z folosi ti z.real respectiv z.imag:
>>> a=1.5+0.5j >>> a.real 1.5 >>> a.imag 0.5

Func tiile de conversie la numere reale sau ntregi nu func tioneaz a pentru numere complexe, neexistnd o metod a matematic a de a transforma un num ar complex ntr-un numar real. Folosi ti func tia abs(z) pentru a calcula modulul, 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 a sat a este atribuit a unei variabile _. Dac a folosi ti Python ca un calculator de birou este mult mai u sor s a p astra ti continuitatea calculelor:
>>> tax = 12.5 / 100 >>> price = 100.50 >>> price * tax 12.5625 >>> price + _ 113.0625 >>> round(_, 2) 113.06 >>>

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

variabila implicit a_s i comportamentul s au extraordinar.

3.1.2

Siruri de caractere

n afar a de numere Python poate manipula s i s iruri de caractere, care pot(exista) avea mai multe forme. Pot incluse 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 secven ta de control \n indicnd astfel ca linia urm atoare este continuarea logic a a liniei curente :
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 a r amne necesar ca semnele de linie nou a s a e incluse n s ir utiliznd \n; linia nou a care urmeaz a ultimului backslash este eliminat a. Acest exemplu va a sa urm atoarele:
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 a construim s irul de caractere ca un s ir raw, atunci secven ta \n nu se converte ste n linie nou a, dar backslesh-ul de la sfr situl liniei s i caracterul de linie nou a din surs a sunt incluse n s ir ca date. Iat a un exemplu :
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

n Python Capitol 3. O introducere scurta

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 s i ntre perechi de cate trei ghilimele sau apostroafe (""" sau ). n acest caz nu ave ti nevoie de caracterele de control (ex: \n\) pentru a realiza separarea liniilor:
print """ Usage: thingy [OPTIONS] -h -H hostname """

Display this usage message Hostname to connect to

are urm atoarea ie sire:


Usage: thingy [OPTIONS] -h -H hostname

Display this usage message Hostname to connect to

Interpretorul a seaz a rezultatul opera tiilor cu s iruri de caractere exact n forma specicat a de utilizator atunci cnd a introdus sau denit s irurile respectiv: ntre ghilimele, cu ghilimele sau alte caractere ciudate, pentru a a sa valoarea exact aas irului. Instruc tiunea print despre care v a vom vorbi mai ncolo poate folosit a pentru a a sa s iruri f ar a ghilimele s i caractere de control. Sirurile de caractere pot concatenate:
>>> word = Help + A >>> word HelpA >>> < + word*5 + > <HelpAHelpAHelpAHelpAHelpA>

Dou as iruri de caractere scrise unul lng a altul sunt concatenate. Prima linie din exemplul de mai sus poate rescris a astfel: word = HelpA. Acest lucru nu merge dect pentru s iruri explicite de caractere, nu pentru orice expresie care are ca operanzi s iruri:
>>> 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 s ir are indicele 0. Nu exist a un tip de date separat pentru caracter. Un singur caracter este reprezentat ca un s ir de lungime unu. Se pot specica de asemenea sub siruri ale unui s ir folosind doi indici, separa ti prin :. Primul indice reprezint a pozi tia de nceput a sub sirului, iar

3.1. Utilizarea Python-ului drept calculator de birou

11

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

Dac a al doilea indice nu este specicat, se consider a c a sub sirul se termin a la sfr situl s irului. Spre deosebire de C, n Python s irurile nu pot modicate. Atribuirea unei valori unui anumit caracter, sau unui sub sir dintr-un s ir 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 s ir nou cu un con tinut combinat este sucient de simpl as i ecient a:
>>> x + word[1:] xelpA >>> Splat + word[4] SplatA

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

Iat a inc a un exemplu:


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

Transmiterea unor parametrii gre si ti, nu genereaz a o eroare, pentru c a n aceast a problem a Python este foarte elegant. Astfel un indice care este prea mare va nlocuit cu dimensiunea s irului:

12

n Python Capitol 3. O introducere scurta

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

Indicii pot s i numere negative, n acest caz se consider a c a indicele zero se a a cel mai la dreapta:
>>> 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, aten tie -0 este acela si lucru cu 0!


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

Indicii negativi mai mari n valoare absolut a dect dimensiunea s irului sunt trunchia ti.Acest lucru nu func tioneaz as i la selectarea unui singur caracter ( nu a unei subsecven te ) :
>>> word[-100:] HelpA >>> word[-10] # error Traceback (most recent call last): File "<stdin>", line 1, in ? IndexError: string index out of range

Mai jos ave ti un tabel care v a va ajuta la n telegerea mecanismului de numerotare al unui s ir de caractere:
+---+---+---+---+---+ | H | e | l | p | A | +---+---+---+---+---+ 0 1 2 3 4 5 -5 -4 -3 -2 -1

Prima linie de numere reprezint a leg atura indicilor pozitivi cu s irul. A doua linie reprezint a coresponden ta dintre caracterele s irului s i indicii negativi. Un sub sir de la i la j este format din toate caracterele dintre cei doi indici i, respectiv j. Pentru indicii pozitivi lungimea sub sirului este dat a de diferen ta indicilor m argina si, dac a nici unul dintre ei nu este mai mare dect lungimea s irului. De exemplu lungimea sub sirului word[1:3] este 2. Func tia len() ntoarce lungimea unui s ir de caractere:
>>> 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 dispozi tia programatorului un nou tip de dat a, pentru manipularea textelor: obiectul Unicode. Poate folosit pentru stocarea s i manipularea datelor de tip Unicode(consulta ti http://www.unicode.org/) s i se integreaz a foarte bine cu obiectele string existente, avnd un mecanism de auto-conversie. Unicode are avantajul c a stabile ste o leg atur a unic a ntre un num ar s i orice caracter scris n scripturi moderne sau scripturi mai vechi. La nceput au existat numai 256 de numere ecare avnd asociat un caracter, s i toate textele erau asociate unei pagini de cod(code page) care f acea leg atura ntre caractere s i numerele asociate. acest lucru a creat foarte mult a confuzie odat a cu interna tionalizarea software-ului. Unicode rezolv a aceste probleme asocind o singur a pagin a tuturor scripturilor. Crearea s irurilor de caractere Unicode este la fel de simpl a ca s i crearea s irurilor obi sniute :
>>> uHello World ! uHello World !

Caracterul u din fa ta s irului indic a interpretorului c a trebuie s a creeze un s ir Unicode din expresia care urmeaz a. Dac a dori ti s a include ti caractere speciale, o pute ti face foarte simplu folosind secven tele Unicode-Escape. Iat a un exemplu:
>>> uHello\u0020World ! uHello World !

Secven ta \u0020 indic a interpretorului s a insereze caracterul cu ordinalul 0x0020 (caracterul spa tiu) npozi tia precizat a. Binen teles c a n acest mod pot introduse s i alte caractere, chiar s i cele obi snuite, folosind valoarea ordinalului s au ca ordinal Unicode. Datorit a faptului c a primele 256 de caractere Unicode sunt acelea si ca s i n nota tia standard ri occidentale, procesul de introducere a caracterelor Unicode devine mult mai simplu. Latin-1, folosit a n multe ta Pentru exper ti exist as i un mod direct(raw-mode) identic ca cel fel ca pentru s irurile normale. naintea s irului trebuie ad augat ur pentru ca Python s a intre n modul Unicode direct. Conversiile \uXXXX sunt utilizate numai dac a este folosit un num ar impar de caractere backslash(\, naintea caracterului u:
>>> urHello\u0020World ! uHello World ! >>> urHello\\u0020World ! uHello\\\\u0020World !

Acest mod poate foarte util dac a ave ti de introdus un num ar mare de backslash-uri. n afar a de metodele de creare a s irurilor Unicode standard, Python ofer a multe alte metode de a crea s iruri Unicode. Func tia built-in unicode() permite accesarea tuturor CODECS-urilor Unicode (CODEC = COderDECoder). Cteva dintre codic arile foarte cunoscute ale caror codex-uri au fost convertite sunt : Latin-1, ASCII, UTF-8 s i UTF-16. Ultimele dou a permit stocarea caracterelor Unicode pe unul sau mai mul ti octe ti. Codicarea implicit a este ASCII, care permite treacerea caracterelor cuprinse ntre 0 s i 127, dar blochez a celelalte caractere semnalnd eroare. Cnd un s ir Unicode este tip arit, scris ntr-un sier, sau convertit cu func tia str(), conversia porne ste utiliznd codarea implicit a.

14

n Python Capitol 3. O introducere scurta

>>> 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 s ir Unicode ntr-un s ir pe 8 bi ti utiliznd o anumit a codicare, obiectele Unicode furnizeaz a metoda encode(), care are un singur argument, numele codului. Este de preferat ca numele codurilor s a se scrie cu litere mici.
>>> u"".encode(utf-8) \xc3\xa4\xc3\xb6\xc3\xbc

Dac a ave ti datele intr-o anume codicare s i dori ti s a ob tine ti un s ir Unicode corespondent din ele, folosi ti func tia 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 dispozi tia programatorului o serie de date structurate, folosite pentru a grupa, a aduna la un loc mai multe valori. Cea mai exibil a astfel de structur a este lista. O list a poate scris a ca o serie de valori separate prin virgul a, s i aat a ntre paranteze p atrate. Elementele unei liste nu trebuie s a e neap arat de acela si tip:
>>> a = [spam, eggs, 100, 1234] >>> a [spam, eggs, 100, 1234]

La fel ca s i la s iruri, primul element al unei liste are indicele 0. n acela si fel ca s i la s iruri, listele pot pozi tionate, concatenate s i a sa mai departe:
>>> 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 s iruri, elementele unei liste pot modicate:


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

Func tia len() se aplic as i listelor :


>>> len(a) 4

Utilizarea sublistelor este de asemenea posibil a. Prin folosirea lor se poate modica chiar s i dimensiunea listei :
>>> # 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 a crea ti liste din alte liste (de exemplu prin concatenare):
>>> >>> >>> 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

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

3.2

Primii pa si n programare

Binen teles c a putem folosi Python s i la alte lucruri dect pentru a aduna 2 cu 2. Putem de exmplu s a gener am o din s subsecven ta irul lui Fibonacci:
>>> ... ... >>> ... ... ... 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 a urm atoarele no tiuni: Prima linie con tine o atribuire multipl a. Varibilele a s i b iau valorile 0 respectiv 1. Pe ultima linie, de asemenea este folosit a atribuirea multipl a. Evaluarea expresiilor din partea dreapt a a unei atribuiri se face nainte de orice atribuire. Evaluarea se face de la stnga la dreapta. Bucla while se execut a atta timp ct b < 10 (atta timp ct condi tia este adev arat a). La fel ca n C, zero nseamn a fals, s i orice num ar diferit de zero nseamn a adev arat. Condi tia poate un s ir, un element de list a, de lungime diferit absolut orice. Orice secven ta a de zero nseamn a adev arat, s i invers. Condi tia folosit a n acest exemplu este o compara tie. Comparatorii standard sunt la fel ca n C: <(mai mic), >(mai mare), ==(egal), <=(mai mic sau egal), >=(mai mare sau egal), !=(diferit). Instruc tiunile din bucl a sunt aliniate. Alinierea (indentation) reprezint a modul n care Python grupeaz a instruc tiunile. Deocamdat a (!) Python nu dispune de un editor n linie de comand a inteligent, astfel nct alinierea, tabularea s a se fac a automat. Sunte ti deci obligat s a folosi ti tab sau spa tii pentru a realiza gruparea instruc tiunilor. Cnd ve ti scrie programe Python ve ti folosi un editor de text. Majoritatea editoarelor de la ora actual a realizeaz a automat tabularea. Pentru a ncheia un bloc de instuc tiuni trebuie introdus a o linie goal a pentru a indica editorului c a editarea blocului de comenzi s-a ncheiat (editorul nu poate ghici cnd a ti introdus ultima linie. Aten tie! ecare instruc tiune dintr-un bloc de instruc tiuni trebuie s a aib a acelea si num ar de spa tii s i taburi nainte, deci instruc tiunile trebuie s a e perfect aliniate. Instruc tiunea print a seaz a expresia pe care o prime ste ca parametru. Sirurile de caractere sunt a sate f ar a ghilimele, s i un spa tiu este inserat ntre elemente, astfel nct a sarea diverselor valori s a mearg a de la sine:
>>> i = 256*256 >>> print Valoarea lui i este:, i Valoarea lui i este: 65536

O virgul a la sfr situl listei de parametrii ai instruc tiunii print, inhib a saltul cursorului pe linia urm atoare la sfr situl instruc tiunii:

3.2. Primii pa si n programare

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

Observa ti c a interpretorul sare la linia urm atoare nainte de a ncepe a sarea, dac a ultima linie a fost incomplet a.

18

n Python Capitol 3. O introducere scurta

CAPITOL

PATRU

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

4.1 Instruc tiuni if


Poate c a cea mai cunoscut a instruc tiune de control este instruc tiunea if. Exemplu:
>>> >>> ... ... ... ... ... ... ... ... ... 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 sec tiuni elif sau niciuna, iar sec tiunea else este op tional a. Cuvntul cheie elif este evident if..elif..elif prescurtarea de la elseif, s i este folositor pentru a evita tabularea excesiv a. O secven ta func tioneaz a ca un bloc case sau switch, secven te proprii altor limbaje .

4.2

Instruc tiuni for

de ce a- Instruc tiunea for din Python difer a un pic fa ta ti ntlnit n C sau Pascal. n loc de o itera tie dat a de o progresie aritmetic a (Pascal), sau de o itera tie foarte exibil a, pentru care programatorul poate deni att pasul itera tiei, ct s i condi tia de oprire (C), itera tiile instruc tiunii Python for func tioneaz a dup a elementele unei secven te (sir sau list 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( si sigur) ca secven ta iterat a s a e modicat a n timpul secven tei for ( este cazul numai al secventelor modicabile, cum ar listele). Dac a apare necesitatea de a modica secven ta n timpul itera tiei, itera tia trebuie s a e asociat a unei copii a secven tei. Nota tia subsecventelor realizeaz a o particularitate convenabil a:
>>> for x in a[:]: # copiaza intreaga lista ... if len(x) > 6: a.insert(0, x) ... >>> a [defenestrate, cat, window, defenetrate]

4.3

Func tia range()

Dac a este necesar a o itera tie pe o mul time de numere, pute ti folosi func tia range() pentru a genera liste ce contin progresii aritmetice :
>>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Paramentrul furnizat func tiei range() nu va niciodat a un membru al secven tei. Este posibil ca func tia range() ncepnd cu un alt num s a genereze o secven ta ar dect 0, sau ra tia progresiei aritmetice poate modicat 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 itera tie pe o mul time de numere folosi ti func tiile range() s i len() astfel:

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

Instruc tiuni break s i continue, s i clauze else pentru bucle

La fel ca n C, instruc tiunea break termin a for tat orice bucl a while sau for. Instruc tiunea continue trece necondi tionat la urm atoarea itera tie. Instruc tiunile iterative pot avea s i o clauz a else. Instruc tiunile din cadrul unei astfel de clauze else sunt executate atunci cnd bucla se termin a odat a cu terminarea listei (for) sau atunci cnd condi tia buclei devine fals a (pentru while) aceste instruc tiuni nu sunt executate dac a bucla este terminat a printr-o instruc tiune break. Iat a un exemplu care determin a numerele prime pn a la 10:
>>> 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

Instruc tiuni pass

Instruc tiunea pass nu execut a nimic. Poate folosit a atunci cnd este necesar a prezen ta sintactic a a unei instruc tiuni, f ar a ca aceasta s a execute ceva:
>>> while 1: ... pass # Asteapta pentru intrerupere de la tastatura ...

4.4. Instruc tiuni break s i continue, s i clauze else pentru bucle

21

4.6

Func tii

Putem crea o func tie care genereaz as irul lui Fibonacci pn a la o limit a arbitrar 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 deni tia unei func tii. Acesteia trebuie s a i urmeze numele func tiei s i o list a parantezat a de parametrii. Instruc tiunile care formeaz a func tia ncep pe linia imediat urm atoare s i trebuie s a e dis de margine. Prima instruc tan tate mai mult dect antetul func tiei fa ta tiune din corpul func tiei poate un s ir de caractere(op tional), acest s ir reprezentnd documenta tia func tiei(docstring = s irul de documenta tie al func tiei). Exist a utilitare care genereaz a documenta tie pornind de la aceste s iruri, deci este o practic a bun a s a v a folosi ti de aceast a facilitate. Execu tia unei func tii creaz a o nou a tabel a de simboluri, folosit a pentru variabilele locale. Altfel spus toate atribuirile din cadrul unei func tii vor stoca valorile n tabela de simboluri local a. Atunci cnd interpretorul g ase ste un nume de variabil a, nti caut a n tabela de simboluri local a, apoi n cea global as i apoi n cea predenit a. Cu toate acestea variabilelor globale nu li se pot atribui valori n cadrul unei func tii, dect dac a se folose ste instruc tiunea global. Parametrii actuali ai unei func tii apelate sunt introdu si n tabela de simboluri local a a celei func tii nmomentul apel arii ei. Astfel transferul aegumentelor se face utilizand apel prin valoare (unde valoare este totdeauna un obiect referin ta , nu valoarea obiectului).1 Cnd o func tie apeleaz a o alta func tie, este creat a o nou a tabel a de simboluri pentru func tia apelat a. Denirea unei func tii trece numele func tiei n tabela de simboluri curent a. Func tia nou creat a este recunoscut a de interpretor ca o func tie denit a de utilizator. n Python exist a un mecanism de redenumire a func tiilor:
>>> fib <function object at 10042ed0> >>> f = fib >>> f(100) 1 1 2 3 5 8 13 21 34 55 89

A ti putea obiecta c a func tia fib este o procedur a nu o func tie. n Python, la fel ca nC, procedurile sunt func tii, numai c a nu returneaz a nici o valoare. Tehnic vorbind, procedurile returneaz a totu si o valoare, aceasta este None(niciuna). None este un cuvnt cheie (predenit). n mod normal valoarea None nu este a sat a de interpretor. Totu si dac a dori ti s a v a convinge ti c a a sa func tioneaz a procedurile ncerca ti urm atorul exemplu:
1 De fapt, apel prin referin ta va putea mai bine descris, atunci daca un obiect modicabil este transmis, apelantul va vedea dac a nurma apelarii 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 a construim o func tie care ntoarce ca rezultat s irul lui Fibonacci:
>>> ... ... ... ... ... ... ... ... >>> >>> [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 a mai multe facilit a ti ale limbajului Python: Instruc tiunea return ntoarce rezultatul func tiei. return f ar a nici un parametru ntoarce ca rezultat al func tiei valoarea None. Pute ti folosi return f ar a parametrii pentru a ncheia execu tia unei func tii nainte de a se ajunge la nalul instruc tiunilor din cadrul func tiei. Valoarea None este de asemenea ntoars a ca rezultat al unei func tii atunci cnd au fost executate toate instruc tiunile procedurii. Instruc tiunea result.append(b) apeleaz a o metod a a obiectului result. O metod a este o func tie care apar tine unui obiect. Metodele sunt apelate folosind sintaxa obj.metod a(unde obj este un obiect, poate s i o expresie, iar metod a este numele metodei ce este apelat a). n func tie de tipul lor, obiectele pot avea diferite metode. Este posibil s a existe metode de tipuri diferite f ar a a se crea confuzii. Este de asemenea posibil s a crea ti obiecte s i metode folosind clasele, dar despre clase vom discuta mai trziu. Metoda append este denit a pentru obiecte de tip list a, s i adaug a un element la sfr situl listei. n acest exemplu ar echivalent a cu result = result + [b] dar mult mai ecient a.

4.7 Mai multe despre func tii


Este posibil n Python s a denim func tii cu un num ar variabil de argumente. Exist a trei modalita ti de a realiza acest lucru, care pot combinate.

4.7.1

Valori implicite pentru argumente

Cea mai util a metod a este s a specica ti valori implicite pentru argumente. n acest fel crea ti o func tie care poate apelat a cu mai pu tine argumente dect a fost denit a:

4.7. Mai multe despre func tii

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

Func tia denit a mai sus poate apelat a n dou a moduri: ask_ok(Sunte ti sigur c a dori ti s a ie si ti?) fi sierul?, 2) sau: ask_ok(Dori ti s a sterge ti

Valorile implicite sunt evaluate n timpul interpret arii deni tiei func tiei, deci urm atoarea secven ta
i = 5 def f(arg=i): print arg i = 6 f()

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

va a sa
[1] [1, 2] [1, 2, 3]

Dac a nu dori ti ca valoarea implicit a s a e re tinut a dup a terminarea func tiei, pute ti proceda ca n exemplul urm ator:
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

Func tiile pot apelate folosind n loc de argumente cuvinte cheie de forma: cuvant_cheie = valoare. Pentru exemplicare observa ti func tia:
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 a n mai multe moduri:


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

Dar urm atoarele apeluri ar genera erori:


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 a de argumente trebuie s a aibe oricte argumente pozi tionale, urmate de oricte argumente de tip cuvinte cheie, unde cuvintele cheie trebuie alese din lista parametrilor formali. Nu este important dac a un parametru formal are o valoare implicit a sau nu. Nici un argument nu poate primi o valoare de mai multe ori numele de parametrii formali corespunz atoare argumentelor pozi tionale nu pot folosite drept cuvinte cheie n cadrul aceluia si apel. Iat a un exemplu cu erori datorate acestei reguli:
>>> 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, func tia va primi o list a care va con tine parametrii de tip cuvnt cheie. Dac a se folose ste un parametru de tipul *nume, func tia va primi o list a con tinnd argumentele suplimentare n afara celor formale. Dac a sunt folosi ti mpreun a parametrul *nume trebuie s a se ae naintea celui de tip **nume. Totul poate p area ambiguu dar ve ti l amuri ti imediat:
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 func tii ar ar ata astfel:

4.7. Mai multe despre func tii

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 atorul:


- 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 func tie poate apelat a cu un num ar arbitrar de argumente. nainte de argumentele arbitrare (op tionale) pot exista 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 augate cteva facilit a ti specice limbajelor func tionale s i Lisp-ului. Folosind cuvntul cheie lambda pute ti crea mici func tii. Iat a o func tie care ntoarce ca rezultat suma argumentelor: lambda a, b : a+b. Formele lambda pot folosite acolo unde sunt necesare func tii obiect. Aceste func tii sunt restrnse sintactic la o singur a expresie:
>>> ... ... >>> >>> 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 documenta tie

Exist a anumite conven tii privind con tinutul s i formatarea s irurilor de documenta tie. Prima linie ar trebui s a e scurt as i foarte concis a. Pentru concizie nu ar trebui precizat numele obiectivului sau tipul, acestea ind subn telese. Aceast a linie trebuie s a nceap a cu liter a mare s i s a se termine cu virgul a.

26

Capitol 4. Structuri de control

Dac a exist a mai multe linii, cea de-a doua ar trebui s a e vid a, pentru a separa descrierea scurt a de cea am anun tit a. Urm atoarele linii ar trebui s a descrie mai pe larg obiectul, semnica tia parametrilor, etc. Interpretorul Python ia n considera tie spa tiile din s irurile de caractere mp ar tite pe mai multe linii, din aceast a cauz a pentru a avea o documenta tie aranjat a frumos trebuie s a v a folosi ti de un mic truc la fel ca n exemplul urm ator:
>>> 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 func tii

27

28

CAPITOL

CINCI

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

5.1

Mai multe despre liste

Tipul de date list a mai dispune de cteva metode. Iat a toate metodele obiectelor de tip list a: append(x) Adaug a un element la sfr situl listei. extend(L) Adaug a la sfr situl listei, elementele listei furnizate ca parametru. insert(i, x) Insereaz a un element ntr-o anumit a pozi tie. Primul argument reprezint a indicele elementului din list a naintea c aruia se va face inser tia, deci a.insert(0,x) va insera elementul x la nceputul listei, iar a.insert(len(a),x) este echivalent cu a.append(x). remove(x) Sterge din list a primul element g asit cu valoarea x. Dac a nu exist a un astfel de element apare o eroare. pop([i ]) Sterge din list a elementul de pe pozi tia i, s i ntoarce valoarea acestuia. Dac a nu este specicat nici un parametru a.pop(), va s terge s i va returna ultimul element din list a. index(x) ntoarce indicele primului parametru din list a care are valoarea x. count(x) ntoarce num arul de apari tii ale valorii x ntre elementele listei. sort() Sorteaz a elementele listei. reverse() Schimb a ordinea elementelor din list a. Iat a un exemplu care folose ste majoritatea metodelor:

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 a pot folosite foarte u sor pentru a simula comportamentul unei stive. Pentru a ad auga un element pe stiv a (PUSH), pute ti folosi append(). Pentru a scoate un element din stiv a (POP), folosi ti pop() f ar a a specica un index. Iat a un exemplu:
>>> >>> >>> >>> [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

Pute ti folosi listele foarte convenabil, pentru a implementa cozi. Spre deosebire de stive unde primul element ad augat este ultimul scos, la cozi primul element ad augat este primul scos. Pentru a ad auga un element folosi ti append(), iar pentru a extrage un element folosi ti pop(0):

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 func tionala

Exist a trei func tii predenite care sunt foarte utile n lucrul cu liste: filter(), map(), reduce(). format Func tia filter() cu sintaxa filter(func tie, secven t a), ntoarce o secven ta a din elementele secven tei specicate ca parametru, care ndepline ste condi tia testat a de func tie. Exemplul care urmeaz a calculeaz 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]

Func tia map() cu sintaxa map(func tie, secven t a), apeleaz a func tia specicat a ca parametru pentru ecare , s element din secven ta i ntoarce o nou a list a format a din rezultatele ntoarse de func tie. Pentru a calcula p atratele similar unor numere dintr-o list a pute ti folosi o secven ta a celei ce urmeaz a:
>>> def cube(x): return x*x*x ... >>> map(cube, range(1, 11)) [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

Func tia map() accept a ca parametrii mai multe secven te. n acest caz func tia transmis a ca parametru trebuie s a e modicat a corespunz ator, trebuie s a accepte acela si num ar de parametrii cte secven te sunt transmise. Dac a secven tele sunt diferite ca lungime, atunci cnd una dintre secven te s-a terminat, n loc de un element func tiei i se transmite None. Dac a n loc de un nume de func tie, se transmite None func tiei map(), atunci func tia va nlocuit a cu o func tie care va ntoarce ca rezultat parametrii primi ti. Pute ti folosi comportamentul func tiei map() pentru a genera perchi de numere provenind din dou a liste:
>>> 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)]

) ntoarce o simpl Func tia reduce(func tie, secven ta a valoare care este calculat a n felul urm ator: este apelat a func tia (care este obligatoriu o func tie binar a ce accept a numai 2 parametrii), cu parametrii primul s i al doilea termen al secven tei, func tia ntoarce un rezultat care mpreun a cu al treilea element sunt transmise din nou func tiei, care genereaz a un alt rezultat s i a sa mai departe, pn a ce lista este epuizat a.

5.1. Mai multe despre liste

31

Exemplul de mai jos calculeaz a suma primelor numere naturale:


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

valoarea acestuia va returnat Dac a exist a un singur element n secven ta a. Dac a lista este goal a, va generat a o excep tie. Func tia reduce() poate primi s i un al treilea parametru care semnic a valoarea de la care ncepe calculul. n acest caz primul apel al func tiei are ca parametrii aceast a valoare s i primul element al listei. Dac a func tia reduce() este apelat a cu trei parametrii, iar lista este goal a, aceasta va ntoarce ca rezultat al treilea parametru. Iat a un exemplu care ilustreaz a modul de lucru al func tiei reduce():
>>> 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 a un mod de a crea liste mult mai concis dect prin intermediul func tiilor map(), filter() sau lambda(). Deni tia listei este de cele mai multe ori mult mai clar a dect cea ob tinut a prin alte metode. Acest mod generalizat, de a genera, a deni liste const a n asocierea unei expresii, cu o clauz a for s i cu niciuna sau mai multe clauze for sau if. Rezultatul va o list a care provine din evaluarea expresiei n contextul clauzelor for s i if ce urmeaz a. Dac a rezultatul evalu arii expresiei va o pereche, atunci expresia trebuie parantezat a corespunz ator:

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 Instruc tiunea del


Exist a o metod a de a s terge un element dintr-o list a specicnd indicele elementului n loc de valoarea elementului. Aceast a metod a poate folosit as i pentru a s terge por tiuni dintr-o list a. Toate acestea pot realizate utiliznd instruc tiunea del:
>>> 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 as i pentru a s terge variabile, de exemplu o ntreag a list a:


>>> del a

Vom vedea mai trziu s i alte modalit a ti de a utiliza instruc tiunea del.

5.2. Instruc tiunea del

33

5.3
1

Perechi s i secven te

Am obsevat pn a acum c a listele s i s irurile de caractere au multe caracteristici comune, de exemplu: indexarea s i . Deoarece Python este un limbaj pozi tionarea (slicing). Sirurile s i listele sunt dou a exemple de tipuri de date secven ta . Exist care evolueaz a, n timp pot ad augate s i alte tipuri de date secven ta as i un alt tip standard de date: perechea (enumerarea). O pereche, o enumerare este format a din mai multe valori separate prin virgule:
>>> 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 a cum pute ti vedea perechile(enumer arile) sunt a sate ntre paranteze astfel nct enumer arile sau perechile mbricate s a e interpretate corect. Perechile pot introduse cu sau f ar a paranteze, ns a, adesea parantezele sunt necesare. Perechile au multe utiliz ari. De exemplu : perechi de coordonate (x,y), nregistr arile angaja tilor dintr-o baz a de date, etc. Pute ti face o analogie (atta timp ct r amne numai o analogie menit a s a v a ajute la n telegerea acestui tip de date) ntre tipurile de date compuse ce pot denite cu struct din C++, s i perechile din Python. Perechile, la fel ca s irurile nu pot modicate: nu pot atribuite valori unui anumit element al unei perechi (pute ti ns a s a simula ti o modicare folosind alte metode). Este posibil s a crea ti perechi care con tin obiecte modicabile, cum sunt listele de exemplu. O problem a deosebit a o constituie crearea perechilor cu zero sau un element. Exist a ns a cteva trucuri de sintax a care pot folosite pentru a rezolva aceast a problem a. Perechile vide pot construite folosind o pereche de paranteze f ar a nimic ntre ele. O pereche cu un singur element poate construit a specicnd valoarea care va con tinut a n pereche urmat a de o virgul a. Cam nepl acut, dar func tioneaz a:
>>> empty = () >>> singleton = hello, >>> len(empty) 0 >>> len(singleton) 1 (hello,)

# <---- observati virgula

Instruc tiunea t = 12345, 54321, Salut! este un exemplu de mpachetare. Valorile 12345, 54321 s i Salut! sunt mpachetate mpreun a. Opera tia invers a este de asemenea posibil a:
>>> x, y, z = t

Aceast a opera tie este numit a sucient de elocvent despachtarea unei secven te. Despachetarea unei secven te necesit a ca lista de variabile de la stnga atribuirii s a con tin a tot attea variabile ct secven ta mpachetat a de la dreapta. De observat este faptul c a mbricarea nu este dect o combina tie succesiv a de mpachet ari sau despachet ari! Ingenios, nu?! Exist a o asimetrie aici: n timp ce o mpachetare va genera ntotdeauna o pereche, despachtarea func tioneaz a pentru
1

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

34

Capitol 5. Strucuri de date

. orice fel de secven ta

5.4

Dic tionare

Un alt tip de date predenit n Python s i care se poate dovedi foarte folositor este dic tionarul. Dic tionarele pot ntlnite s i n alte limbaje, sub alte nume, cum ar memorii asociative sau valori asociative. Spre deosebire de secven te (liste, s iruri, etc.) care sunt indexate cu numere (indicii sunt numere), dic tionarele sunt indexate de chei, care pot denite de oricare din tipurile de date invariabile(nemodicabile), de exemplu: s iruri de caractere sau numere. Perechile pot folosite drept chei ale unui dic tionar numai dac a con tin obiecte invariabile. Nu pute ti folosi drept chei listele deoarece acestea pot modicate folosind metode ca append() sau extend(). Este indicat s a v a gndi ti la un dic tionar ca la o mul time neordonat a de perechi cheie-valoare, cu observa tia c a o cheie trebuie s a e unic a ntr-un dic tionar. O pereche de acolade creaz a un dic tionar gol: {}. Pute ti crea un dic tionar dac a ntre acolade introduce ti o list a (ale c arei elemente sunt separate prin virgul a), de perechi cheie-valoare: dic tionar = jack:4098, Sape:4139. Opera tiile principale pe care le realizeaz a un dic tionar sunt: stocarea unei valori cu anumit a cheie s i extragerea unei valori cunoscndu-se o anumit a cheie. O pereche cheie-valoare poate s tears a folosind instruc tiunea del. Dac a se adaug a o valoare n dic tionare pentru o cheie care exist a deja, valoarea veche asociat a acelei chei este pierdut a. O eroare este generat a, binen teles, dac a ve ti ncerca s a extrage ti o valoare pentru o cheie inexistent a. Metoda keys() a unui obiect dic tionar ntoarce o list a cu toate cheile existente n respectivul dic tionar. Lista returnat a nu este sortat a, ns a pentru a o sorta pute ti folosi metoda sort() a obiectului list a returnat de func tie. Pentru a verica dac a o anumit a cheie se a a deja n dic tionar folosi ti metoda has-key(). Iat a un mic exemplu:
>>> 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 condi tii


Condi tiile folosite n cadrul instruc tiunilor while sau if pot con tine s i al ti operatori dect cei de compara tie. dat Operatorii de compara tie in s i not in veric a dac a o anumit a valoare se a a sau nu ntr-o secven ta a. Operatorii is s i is not veric a dac a dou a obiecte sunt de fapt unul s i acela si obiect, acest lucru conteaz a n cazul obiectelor modicabile cum sunt listele de exemplu. Operatorii de compara tie pot combina ti. De exemplu a < b == c testeaz a nti dac a a < b iar apoi dac a b este egal cu c. Condi tiile pot avea structuri foarte complexe dac a sunt folosi ti operatorii and, or sau not. Operatorii de compara tie au aceea si prioritate care este mai mic a dect aceea a operatorilor numerici. Operatorii logici, booleeni(and,or,not) au cea mai mic a prioritate, mai mic a dect aceea a operatorilor de compara tie. Cea mai mare prioritate ntre operatorii logici o au not, apoi and, iar cea mai mic a or. n concluzie A and not B or 5.4. Dic tionare 35

C este echivalent cu A and (not B) or C. Binen teles pute ti folosi paranteze pentru a combina condi tiile s i pentru claritate. Operatorii logici mai sunt denumi ti s i operatori pe scurt atur a (shortcut operator), argumentele acestea sunt evaluate de la stnga la dreapta, s i evaluarea se opre ste odat a ce rezultatul este determinat. De exemplu dac aAs i C sunt adev arate, iar B fals, expresia A and B and C nu este evaluat a pn a la sfr sit, deci expresia C nu este evaluat a pentru c a ar inutil. Este posibil a atribuirea unei valori rezultate dintr-o compara tie sau orice alt a condi tie, unei variabile:
>>> 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 a o mul time de erori ntlnite n programele C, de exemplu = n loc de ==.

5.6 Compararea secven telor


pot comparate cu obiecte secven de acela Obiectelor de tip secven ta ta si tip. Compara tiile ntre secven te folosesc principiile ordon arii lexicograce: sunt comparate nti primele dou a elemente din ecare list a, dac a difer a rezultatul este a sat, dac a sunt egale se trece la compararea urm atoarelor dou a elemente, s i a sa mai departe pn a la epuizarea uneia dintre liste. Dac a elementele ce urmeaz a a comparate sunt la rdul lor liste, compararea lexicograc a are loc recursiv. Dac a toate elementele celor dou a liste sunt egale se consider a c a listele sunt egale. Dac a una dintre secven te a ini mai scurt este o subsecven ta tial a a celeilalte, atunci secven ta a este cea mai mic a. Ordonarea lexicograc a pentru s iruri folose ste ordinea ASCII a caracterelor. Exemple de compara tii ntre secvenc te de acela si tip:
(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 a arbitrar: tipurile ind ordonate dup a numele lor. n concluzie o list a va ntotdeauna mai mic a dect un s ir, un s ir mai mic dect o pereche, etc. Compara tiile ntre numere se fac lund n considera tie valoarea numeric a chiar dac a numerele sunt de tipuri diferite, s i ca atare 0 va egal cu 0.0, etc. 2

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

36

Capitol 5. Strucuri de date

CAPITOL

SASE

Module
Dac a ie si ti din interpretorul Python s i intra ti din nou, deni tiile pe care le-a ti f acut (func tii, varibile, etc.) se pierd. Dac a ave ti de gnd s a scrie ti un program mai lung, ar mai bine s a folosi ti un editor de texte pentru a scrie programul ntr-un sier, s i apoi s a rula ti interpretorul Python cu parametru sierul n care se a a programul. Fi sierul n care se a a programul se nume ste script. Pe m asur a ce programul se va m ari ve ti sim ti nevoia s a l mp ar ti ti n mai multe siere. S-ar putea la fel de bine s a dori ti s a folosi ti o func tie n mai multe programe f ar a a nevoit s a copia ti deni tia func tiei n ecare program. n Python pute ti scrie anumite deni tii ntr-un sier, pe care l pute ti include n alte programe. Un astfel de sier se nume ste modul. Deni tiile dintr-un modul pot importate n alte module, sau n modulul principal (programul ini tial). Un modul este un sier care con tine deni tii s i instruc tiuni Python. Numele sierului n care se a a un anumit modul este dat de numele modulului s i extensia .py la sfr sit. ntr-un modul, numele acestuia este accesibil prin intermediul variabilei globale __name__. Folosi ti acum editorul dumneavoastr a de texte preferat pentru a creea sierul bo.py:
# 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 deschide ti interpretorul Python s i tasta ti comanda:


>>> import fibo

Aceast a instruc tiune nu ncarc a n tabela de simboluri numele func tiilor denite n modulul bo, ci numai numele modulului. Folosind numele modulului pute ti accesa func tiile denite n interiorul acestuia:

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 a deranjeaz a aceste nume lungi pute ti proceda n felul urm ator:
>>> 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 con tine att instruc tiuni executabile ct s i deni tii de func tii. Aceste instruc tiuni sunt menite s a realizeze ini tializarea modulului s i se execut a o singur a dat a atunci cnd modulul este importat. Fiecare modul are propria sa tabel a de simboluri care este folosit a de func tiile denite n modul ca o tabel a de simboluri global a. Cu toate astea, autorul unui modul se poate folosi de variabilele globale, f ar a a- si face griji pentru eventuale coliziuni cu variabilele globale ale mediului n care modulul va importat. Pe de alt a parte dac a ave ti neap arat nevoie pute ti modica direct variabilele globale ale unui modul, folosind aceea si conven tie ca la apelarea func tiilor unui modul: modul.variabil a. Modulele pot importa alte module. Instruc tiunile import pot plasate la nceputul programului s i este indicat, dar nu este obligatoriu. Exist a o metod a de a nc arca deni tiile unui anumit modul direct n tabela de simboluri global a a modulului care 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 a. Pentru a nc arca toate deni tiile modulului direct n tabela local a folosi ti: n exemplul de mai sus, n tabela local a au fost nc arcate toate numele de variabile s i func tii, mai putin cele care ncep 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 a un sier numit xxx.py n directorul curent, s i n toate directoarele specicate n variabila de sistem PYTHONPATH. Aceasta are aceea si sintaxa variabila de sistem

38

Capitol 6. Module

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

6.1.2

Fi siere Python compilate

Un important aport de vitez a la pornirea programelor care ncarc a o mul time de module standard este adus de urm atorul comportament al Python-ului: dac a n directorul unde este g asit sierul xxx.py se mai a as i xxx.pyc, se presupune c a acest ultim sier con tine o variant a compilat a a modulului s i este nc arcat n loc de xxx.py. Timpul la care a fost modicat ultima oar a sierul .py este nregistrat n sierul .pyc n momentul n care este creat, iar n momentul importului dac a aceste momente de timp nu corespund sierului .pyc este ignorat. De obicei nu trebuie s a face ti nimic deosebit pentru a crea sierul xxx.pyc. Oridecteori xxx.py este compilat cu succes este creat sau suprascris s i sierul xxx.pyc. Dac a scrierea sierului compilat nu reu se ste ve ti avertizat printrun mesaj de eroare. Con tinutul sierelor de tip .pyc este independent de platform a, astfel nct Python devine un limbaj foarte portabil. Cteva indica tii pentru exper ti: Cnd interpretorul Python este apelat folosind op tiunea -O, se genereaz a cod optimizat care va stocat n siere de tip .pyo. La momentul actual optimizatorul nu este de prea mare folos, nu face dect s a elimine din cod instruc tiunile assert s i SET-LINENO. Atunci cnd se folose ste aceast a op tiune tot codul este optimizat, sierele .pyc sunt ignorate iar sierele .py sunt compilate s i optimizate. Dac a interpretorul Python este lansat n execu tie folosind op tiunea -O, compilatorul poate genera n anumite cazuri cod compilat eronat. Versiunea curent a elimin as irurile __doc__ din codul compilat, astfel nct acesta s a e mai compact. Din moment ce unele programe pot folosi aceste s iruri, eliminarea lor ar putea genera erori. n concluzie, ar trebui s a folosi ti aceast a op tiune numai atunci cnd s ti ti foarte bine ce face ti. de unul Un program nu func tioneaz a mai rapid, atunci cnd este citit dintr-un sier de tip .pyc sau .pyo, fa ta .py. Singurul lucru care difer a este viteza de nc arcare a programelor n memorie. Atunci cnd un script este rulat, prin lansarea interpretorului s i parametru numele sierului n care se a a scriptul, codul script-ului nu este compilat s i nu se genereaz a siere de tip .pyc sau .pyo. n cazul n care ave ti un script de dimensiuni mari, s i dori ti s a cre ste ti viteza de nc arcare, pute ti s a muta ti buc a ti din cod ntr-un modul pe care s a l importa ti apoi n script. Interpretorul Python poate lansat s i folosind direct un sier cu extensia .pyc sau .pyo. Este posibil s a lansa ti interpretorul Python doar cu un sier de tip .pyc (sau .pyo dac a se folose ste -O), f ar a ca sierul .py asociat s a existe. Pute ti folosi aceast a facilitate atunci cnd distribui ti o bibliotec as i nu dori ti s a e modicat a. Modulul compileall poate folosit pentru a crea siere .pyc sau .pyo pentru toate modulele dintr-un director.

6.2

Module standard

Python dispune de o bilbliotec a de module standard, a c aror descriere o pute ti g asi ndocumentul The Python Library Reference. Unele module sunt integrate n interpretor, de si nu fac parte din nucleul limbajului, din deni tia acestuia, sau pentru a facilita accesul la primitivele sistemului de operare. Setul de module dar sunt integrate pentru ecien ta integrate este o optiune de congurare, care de asemenea depinde de particularitatea platformei. De exemplu modulul amoeba este disponibil pe sisteme care pun la dispozi tie primitive Amoeba. Un anumit modul necesit a o aten tie special a: sys care este integrat n orice interpretor Python. Variabilele sys.ps1 s i sys.ps2 denesc s irurile de caractere ce vor folosite de interpretor pentru prompt-ul principal s i cel secundar:

6.2. Module standard

39

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

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

6.3

Func tia dir()

Func tia integrat a dir() poate folosit a pentru a determina ce nume(de variabile, func tii, etc.) dene ste un modul. Rezultatul acestei func tii este o list a sortat a de s iruri de caractere:
>>> 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 a func tia dir() este apelat a f ar a argumente, va lista numele ce sunt denite (local) pn a n momentul curent:
>>> a = [1, 2, 3, 4, 5] >>> import fibo, sys >>> fib = fibo.fib >>> dir() [__name__, a, fib, fibo, sys]

Observa ti c a listeaz a diferite tipuri de nume: variabile, func tii, module, etc. dir() nu listeaz a s i numele de func tii sau variabile integrate. Dac a dori ti o astfel de list a, pute ti apela dir(__builtin__), unde __buildin__ este modulul n care se a a func tiile s i variabilele integrate:

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 a modul de acces la module( si la deni tiile existente n module). Pentru exemplicare numele modulului A.B desemneaz a un submodul B denit n cadrul pachetului A. S a presupunem c a dori ti s a proiecta ti o colec tie de module (un pachet) pentru manipularea sierelor de sunet, s i a sunetelor. Exist a o multitudine de formate de sunet (de obicei recunoscute dup a extensia lor .wav, .aiff, .au) a sa c a este necesar a creearea s i ntre tinerea unei colec tii de module ncontinu a cre stere care s a permit a conversia ntre diverse formate de siere. Exist a multe alte opera tii pe care poate a ti dori s a le executa ti (mixaje, ad augarea ecoului, efecte stereo, etc.), a sa c a, de fapt, ve ti scrie o serie nesfr sit a de module care s a permit a aceste opera tii. Ave ti mai jos o posibil a structur a a pachetului dumneavoastr a (n sensul unei ierahii de siere):
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

Fi sierele de tipul __init__.py sunt necesare pentru a face Python s a trateze directoarele ca pachete. Acestea sunt necesare pentru a preveni situa tia ca un director cu un nume comun, de exemplu string, s a ascund a un modul valid cu acela si nume. n cel mai simplu caz __init.py__ poate un sier gol, dar poate con tine s i cod de ini tializare. Utilizatorii unui pachet pot importa doar un anumit modul din cadrul pachetului: 6.4. Pachete 41

import Sound.Effects.echo

Instruc tiunea de mai sus a nc arcat modulul Sound.Effects.echo, dar o func tie din cadrul modulului trebuie aplelat a folosindu-i numele ntreg.
Sound.Effects.echo.echofilter(input, output, delay=0.7, atten=4)

O alternativ a pentru a importa un modul este:


from Sound.Effects import echo

n acest moment numele denite n modul au fost nc arcate n tabela local a de simboluri, deci numele de func tii s i variabile sunt disponibile f ar a prex:
echo.echofilter(input, output, delay=0.7, atten=4)

O alt a variant a este nc arcarea (importarea) direct a a func tiei sau variabilei dorite:
from Sound.Effects.echo import echofilter

Un exemplu de utilizare a func tiei echofilter():


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

De observat c a atunci cnd se folose ste sintaxa from packet import element, elementul poate , e un submodul (sau subpachet), e un nume denit n pachet, de exemplu un nume de func tie sau variabil a, sau un nume de clas a. Instruc tiunea import testeaz a nti dac a elementul este denit sau nu n pachet. Dac a elementul nu este denit, Python presupune c a este vorba de un modul s i ncearc a s a-l ncarce. Dac a nc arcarea nu reu se ste este generat ao excep tie de tipul ImportError. Cnd folosi ti o sintax a de genul: import element.subelement.subsubelement, ecare element, mai pu tin ultimul trebuie obligatoriu s a e un pachet. Ultimul element poate un modul, un pachet, dar nu poate o clas a, o func tie, o variabil a, etc. denit a n elementul anterior.

6.4.1

Importarea tuturor modulelor dintr-un pachet

Ce se va ntmpla dac a un programator va folosi o instruc tiune de genul: from Sound.Effects import *? ntr-un caz ideal, programatorul ar putea s a spere c a interpretorul Python va realiza o c autare recursiv a n sistemul de siere s i directoare dup a modulele existente n pachet. Din nefericire nu func tioneaz a foarte bine pe platforme Mac sau Windows, din varii motive. Pe astfel de platforme existen ta unui sier ECHO.PY nu garanteaz a c a n acest sier se a a un modul numit Echo, ct s i echo sau ecHo, s i a sa mai departe. Spre exemplu Windows 95 are prostul obicei de a a sa numele de siere cu prima liter a mare. Sistemul de siere DOS 8+3 ridic a o alt a piedic a n calea numelor lungi de module. Singura solu tie pentru astfel de probleme este ca autorul pachetului s a specice exact ce module exist a n pachet. Instruc tiunea import() folose ste urm atoarea conven tie: dac a codul existent n sierul __init__.py dene ste o list a cu numele __all__, aceasta este considerat a lista cu modulele ce ar trebui nc arcate la execu tia unei instruc tiuni from pachet import *. Este obliga tia autorului pachetului s a modice lista atunci cnd este cazul. Autorii de pachete pot lua de asemenea decizia de a nu deni aceast a list a, dac a nu vor ca programatorul care folose ste pachetul s a execute instruc tiuni de genul import *. Fi sierul Sounds/Effects/__init__.py ar trebui s a con tin a urm atoarele: 42 Capitol 6. Module

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

n acest caz instruc tiunea from Sound.Effects import * ar nc arca cele trei submodule ale modulului Sound. Dac a variabila __all__ nu este denit a, instruc tiunea de import nu va importa toate submodulele ci va importa numai pachetul Sound.Effects (eventual va executa codul de ini tializare din __init__.py) s i apoi va importa toate numele denite n pachet. Se vor importa s i submodulele pachetului dac a acest lucru este specicat prin instruc tiuni import. Privi ti urm atorul cod :
import Sound.Effects.echo import Sound.Effects.surround from Sound.Effects import *

n exemplul anterior, modulele echo s i surround sunt importate deoarece acest lucru este specicat (prin instruc tiuni import) n cadrul pachetului Sound.Effects. Nu este foarte ecient s a folosi ti instruc tiuni de tipul import *, pentru c a n acest fel codul dumneavoastr a va deveni neclar, neind clar care anume module sunt nc arcate. Totu si dac a a ti lansat interpretorul n mod interactiv, pute ti folosi astfel de instruc tiuni pentru a evita scrierea multor instruc tiuni. n concluzie nu este nimic gre sit n folosirea unei instruc tiuni similare cu from Packet import submodul, de fapt aceasta este nota tia recomandat a.

6.4.2

Referen tieri ntre pachete

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

6.4. Pachete

43

44

CAPITOL

SAPTE

s Intrari i ie siri
Exist a cteva modalit a ti de a prezenta rezultatele unui program. Datele pot a sate ntr-un format care poate n teles de om, sau pot scrise ntr-un sier pentru a putea prelucrate mai trziu. Acest capitol va explica cteva dintre posibilit a ti.

7.1

a datelor la ie Formatarea mai eleganta sire

Pn a acum am ntlnit dou a metode de a a sa valori: instruc tiunea print s i expresii. (O a treia metod a este folosind metoda write() a obiectelor de tip sier. Fi sierul standard de ie sire este referit ca sys.stdout.) Adesea ve ti dori s a ave ti mai mult control asupra modului de a sare a valorilor. Exist a dou a metode pentru a controla modul de a sare: prima este s a modica ti singur un s ir de caractere, folosind diversele opera tii existente, iar apoi s a l a sa ti. Modulul string con tine cteva opera tii utile pentru manipularea s irurilor de caractere. O a doua metod a este folosirea operatorului %, cu un s ir, ca argument stnga. Operatorul % interpreteaz a argumentul stnga n acela si mod ca s i s irul de formatare al func tiei C sprintf() aplicndu-l asupra argumentului din dreapta s i returnnd s irul rezultat n urma ecestei format ari. O singur a ntrebare r amne: cum pot convertite valorile n s iruri de caractere? Din fericire Python poate converti orice tip de valoare n s ir de caractere: e prin func tia repr(), e scriind valoarea ntre apostroafe (). Iat a cteva exemple: Pn a acum am ntlnit dou a metode de a a sa valori: instruc tiunea print s i expresii. (O a treia metod a este folosind write() a obiectelor de tip sier. Fi sierul standard de ie sire este referit ca sys.stdout.)
>>> 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 a dou a modalit a ti de a genera un tabel cu p atratele s i cuburile numerelor naturale: 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

Observa ti c a ntre coloane a fost ad augat un spa tiu. Acest comportament este asigurat de modul n care lucreaz a instruc tiunea print: ntotdeauna adaug a un spa tiu ntre argumentele sale. Acest exemplu demonstreaz a utilizarea func tiei string.rjust(), care aliniaz a la dreapta un s ir de caractere, ntr-un cmp de o anumit a dimensiune dat a, introducnd spa tii la stnga s irului. Exist a s i alte func tii similare string.ljust(), string.center(). Aceste func tii nu a seaz a nimic, nu fac dect s a returneze un alt s ir de caractere. Dac as irul primit este mai lung, aceste func tii nu l modic a, ci l returneaz a intact. Acest mecanism probabil c a v a va strica aranjarea pe coloane, dar este o variant a preferabil a celeilalte, adic a trunchierea s irului. Dac a dori ti s a truchia ti un s ir, pute ti oricnd s a folosi ti opera tiile de por tionare (slicing), ca de exemplu: string.ljust(x,n)[0:n]. Mai exist a o func tie util a, care umple cu zero-uri un s ir, ad augndu-le la stnga s irului original, pn a cnd acesta ajunge la o anumit a dimensiune. Aceast a func tie este string.zfill():
>>> 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 ata astfel:

46

s Capitol 7. Intrari i ie siri

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

Dac a exist a mai multe format ari n s ir, trebuie s a se transmita ca operator dreapta o pereche ( tupla ), astfel :
>>> 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 func tioneaz a exact ca n C, s i nu necesit a dect transmiterea corect a a operandului din dreapta. Nerespectarea acestei reguli va genera o excep tie. Specicatorul de format %s este mai exibil, dac a parametrul asociat din partea dreapt a nu este de tip s ir de caractere, va automat convertit la s ir de caractere folosind func tia integrat a str(). Specicatorii de format %u s i %p din C nu sunt accepta ti s i de Python. Dac a ave ti un s ir lung pe care nu dori ti s a-l mp ar ti ti n mai multe s iruri, ar interesant s a v a pute ti referi la variabile prin nume n loc de pozi tie. Acest lucru poate realizat folosind modalitatea numevariabil a format, ca 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 dori ti s a a sa ti variabilele predenite folosind func tia vars() care ntoarce un dic tionar cu toate variabilele locale.

7.2

Fi siere

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

Primul argument este un s ir de caractere care con tine numele sierului ce urmeaz a s a e deschis. Al doilea argument este tot un s ir de caractere ce con tine doar cteva caractere ce descriu modul n care sierul va utilizat. Modul poate : - r = sierul va putea numai citit - w = sierul va putea dect s a e scris (n cazul n care un sier exist a deja, acesta va suprascris) - a = sierul va deschis pentru actualizare (toate datele scrise vor ad augate la sfr situl sierului) - r+ = n sierul ce va deschis se pot executa att opera tii de scriere ct s i de citire. 7.2. Fi siere 47

Pe Windows s i Macintosh ad augarea caracterului b la sfr situl s irului prin care se specic a modul de acces, indic a interpretorului Python s a deschid a sierul n mod binar. Exist a deci modurile de acces rb, wb, r+b. Windows face distinc tie ntre sierele de tip text s i cele binare: caracterele de sfr sit de linie sunt modicate atunci cnd se scriu sau se citesc date. Aceaste modic ari din spatele scenei sunt binevenite n cazul sierelor text, dar nu pot face dect r au n cazul sierelor binare cum sunt .JPG sau .EXE de exemplu. Ave ti deci grij a s a folosi ti modul binar cnd lucra ti cu astfel de siere.

7.2.1

Metodele obiectelor sier

Exemplele acestei sec tiuni vor presupune c a un obiect f de tip sier a fost deja creat, deci sierul a fost deja deschis. Pentru a citi con tinutul unui sier apela ti f.read(dimensiune), care cite ste o cantitate de date s i o returneaz a ca string. Parametrul dimensiune este op tional. Atunci cnd acest parametru este omis sau este negativ, ntregul sier va citit s i returnat ca s ir de caractere. Apare o problem a binen teles dac a memoria ma sinii dumneavoastr a este mai mic a dect dimensiunea sierului. Dac a parametrul dimensiune este transmis func tiei din sier vor citi ti cel mult at tia bytes c ti sunt specica ti prin acest parametru. Dac a s-a ajuns la sfr situl sierului f.read() va returna un s ir vid(" "):
>>> f.read() This is the entire file.\n >>> f.read()

Metoda f.readline() cite ste o singur a linie din sier. Un caracter linie nou a(newline), \n este ad augat la sfr situl ec arui s ir. Acest caracter este omis dac a este vorba despre ultima linie din sier s i dac a acesta nu se termin a cu un caracter linie nou a. Toate acestea fac rezultatul neclar. Dac a rezultatul este un s ir gol, atunci a fost atins sfr situl sierului, n timp ce dac a rezultatul este doar caracterul \n nseamn a c a din sier a fost citit a o linie goal 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 sier, ntoarce o list a con tinnd toate liniile din sier. Dac a metoda este apelat a cu argumentul dimensiune, atunci din sier sunt citi ti at tia bytes c ti sunt specica ti prin acest parametru s i nc a at tia bytes c ti sunt necesari pentru a completa o linie. Aceast a metod a este folosit a pentru citirea ecient a pe linii a sierelor de dimensiuni mari f ar a a ntmpina dicult a ti cu memoria. Vor returnate numai linii complete:
>>> f.readlines() [This is the first line of the file.\n, Second line of the file\n]

Metoda write(s ir) scrie con tinutul s irului de caractere n sier, ntorc and None ca rezultat:
>>> f.write(This is a test\n)

f.tell() are ca rezultat un num ar ntreg reprezentnd pozi tia cursorului n sier, pozi tie m asurat a n bytes fa ta de nceputul sierului. Pentru a schimba pozi tia cursorului folosi ti func tia f.seek(deplasare,referin t a). 48 s Capitol 7. Intrari i ie siri

de nceputul Noua pozi tie este calculat a n felul urm ator: cursorul va deplasat cu deplasare bytes, fa ta sierului de pozi de sfr dac a referin t a este 0, fa ta tia curent a a cursorului dac a referin t a este 1 s i fa ta situl sierului dac a referin t a este 2. Dac a al doilea parametru este omis, valoarea lui implicit a va 0, deci punctul de referin ta va nceputul sierului:
>>> >>> >>> >>> 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 termina ti lucrul cu un sier, acesta trebuie nchis folosind f.close(). Dup a nchiderea sierului orice ncercare de opera tie asupra sierului va e sua:
>>> f.close() >>> f.read() Traceback (most recent callk last): File "<stdin>", line 1, in ? ValueError: I/O operation on closed file

Obiectele sier posead as i alte metode, cum ar isatty() s i truncate() care sunt mai pu tin folosite. (Consulta ti "Python Library Refference" pentru mai multe detalii).

7.2.2

Modulul pickle

Sirurile de caractere pot citite s i scrise foarte u sor dintr-un, respectiv ntr-un sier. Cu numerele lucrurile se complic a pu tin. A ti putea s a transforma ti nainte de scrierea n sier, num arul n string, apoi s a l scrie ti, iar la citire s a l transforma ti napoi n num ar, dar un astfel de mecanism este complet inecient. Pentru aceste situa tii, s i altele mult mai complicate Python dispune de modulul pickle care poate transforma orice obiect Python ntr-un string. Acest proces se cheam a pickling, denumirea procesului invers se nume ste unpickling. ntre aceste dou a proceduri string-ul poate salvat ntr-un sier, transmis n re tea, etc. Cea mai simpl a metod a de a salva un obiect ntr-un sier este urm atoarea:
pickle.dump(x, f)

Iar pentru a nc arca un obiect dintr-un sier:


x = pickle.load(f)

Exist as i alte metode de a transforma un obiect ntr-un s ir f ar a a-l salva ntr-un sier. Pentru mai multe detalii consulta ti Python Library Refference. Prin procedeele de pickling s i 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 a extensii ale limbajului Python au grij a ca tipurile de date nou denite s a poat a salvate s i nc arcate corect(mai bine zis s a se comporte corect n procesul de pickling s i apoi unpickling).

7.2. Fi siere

49

50

CAPITOL

OPT

Erori s i excep tii


Pn a acum erorile au fost doar men tionate, dar dac a a ti ncercat exemplele prezentate probabil a ti s i ntlnit cteva dintre ele. Exist a (cel pu tin) dou a categorii de erori: erori de sintax as i excep tii.

8.1

Erori de sintaxa

Erorile de sintax a sunt cel mai des ntlnite erori atta timp ct sunte ti un ncep ator n limbajul Python:
>>> 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 s i a seaz a o s ageat a n dreptul instruc tinii care a generat eroarea. Eroarea este cauzat a (sau cel pu tin detectat a) de instruc tiunea dinaintea s age tii. n exemplul de mai sus eroarea este generat a de instruc tiunea print, deoarece naintea acestei instruc tiuni ar trebui s a existe un caracter :. Numele sierului s i num arul liniei care a generat eroarea sunt a sate, astfel nct dac a eroarea provine dintr-un script s a pute ti corecta ct mai comod.

8.2

Excep tii

Chiar dac a o expresie sau o instruc tiune este corect a din punct de vedere sintactic, aceasta poate genera o eroare n momentul n care este executat a. Erorile generate (detectate) n timpul execu tiei se numesc excep tii, s i nu sunt neap arat fatale. Ve ti ntreba cum pute ti evita astfel de erori utiliznd limbajul Python. Majoritatea excep tiilor nu sunt tratate de program s i genereaz a mesaje de eroare ca n exemplul de mai jos:

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 a ce s-a ntmplat. Excep tiile sunt de diferite tipuri, iar tipul excep tiei este de asemenea a sat n corpul mesajului de eroare. n exemplul anterior: ZeroDivisionError, NameError s i TypeError, s irul a sat ce desemneaz a tipul excep tiei este un nume predenit pentru respectivul tip de excep tie. Acest lucru este valabil pentru toate excep tiile predenite, dar se pot deni s i alte tipuri de excep tii. A doua parte a liniei reprezint a detaliile excep tiei, descriind mai bine ce s-a ntmplat. n Python Library Reference sunt listate excep tiile implicite s i semnica tiile lor.

8.3 Tratarea excep tiilor


Este posibil s a scrie ti programe care trateaz a anumite tipuri de excep tii . n urm atorul exemplu este implementat ao bucl a care cere utilizatorului introducerea unui num ar. Bucla este ntrerupt a n momentul n care utilizatorul introduce un num ar corect, astfel procesul de introducere continu a. Procesul poate ntrerupt folosind combina tia de taste CTRL-C. Dac a utilizatorul folose ste aceast a combina tie de taste, programul este ntrerupt, dar nainte este generat a excep tia: KeyboardInterrupt:
>>> while 1: ... try: ... x = int(raw_input("Please enter a number: ")) ... break ... except ValueError: ... print "Oops! That was no valid number. Try again..." ...

Instruc tiunea try func tioneaz a n felul urm ator: nti sunt executate instruc tiunile din blocul try (blocul de instruc tiuni dintre instruc tiunile try s i except). Dac a nu este generat a nici o excep tie, instruc tiunile din blocul except nu sunt executate s i programul continu a. Dac a apare o excep tie n timpul execu tiei instruc tiunilor din blocul try s i dac a tipul excep tiei este acela pe care l trateaz as i blocul except, atunci instru tiunile din acest bloc nu sunt executate. Dup a ce excep tia este tratat a, execu tia continu a, nemai executndu-se instruc tiunile r amase din blocul try (adic a instruc tiunile ce urmeaz a dup a instruc tiunea care a generat excep tia). Dac a excep tia nu este prev azut a ntre excep tiile tratate n blocul except, ea este transmis a altor structuri try.Dac a nu este g asit un bloc except care s a trateze excep tia, programul este ntrerupt, iar respectiva excep tie se nume ste excep tie netratat a (unhandled exception).

52

Capitol 8. Erori s i excep tii

O instruc tiune try poate avea mai multe clauze except, implementnd astfel mai multe tipuri de tratament pentru mai multe tipuri de excep tii. Dintre toate clauzele except va executat a cel mult una. Instruc tiunile unei clauze except, trateaz a numai excep tiile generate n blocul try c aruia clauza i este asociat a, nu s i excep tiile ce pot apare n alte clauze except. O astfel de clauz a poate trata mai multe tipuri de excep tii desemnate printr-o lista inchis a ntre paranteze, ca de exemplu :
... except (RuntimeError, TypeError, NameError): ... pass

Ultima clauz a except poate folosit a f ar a a se specica ce anume excep tie trateaz a, n acest caz aceast a clauz a trateaz a toate excep tiile netratate de celelalte clauze. Pute ti folosi aceast a ultim a precau tie, s i este indicat s a o face ti, pentru a ascunde toate erorile ce pot ap area s i pe care nu le-a ti anticipat. O pute ti de asemenea folosi pentru a a sa un mesaj de eroare s i apoi a regenera excep tia, care va transmis a mai departe, urmnd s a e eventual tratat a de un alt 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

Instruc tiunile try dispun s i de o clauz a op tional a: else. Atunci cnd aceasta este folosit a, ea trebuie s a e ultima dintre clauze. Instruc tiunile acestei clauze vor executate atunci cnd, blocul try nu genereaz a nici o excep tie. Iat 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 a dect ad augarea unor linii suplimentare de cod la sfr situl blocului try, pentru c a n acest fel se evit a detectarea unei excep tii care nu a fost generat a de instruc tiunile blocului try. O excep tie poate avea asociat as i o valoare, un argument al excep tiei. Prezen ta argumentului s i tipul acestuia depinde de tipul excep tiei. Pentru acele excep tii care au un argument, clauza except poate avea nume de varibil a, dup a numele excep tiei, variabil a ce va con tine(dac a acea excep tie este detectat a) argumentul asociat excep tiei. Urm atorul exemplu este l amuritor n acest sens:

8.3. Tratarea excep tiilor

53

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

Dac a o excep tie are un argument, acesta va a sat n ultima parte a mesajului ce apare cnd o excep tie nu este tratat a. ntr-un bloc try nu sunt detectate numai excep tiile generate n cadrul func tiilor apelate:
>>> 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 excep tiilor

Instruc tiunea raise i permite programatorului s a genereze o anumit a excep tie :


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

Primul parametru reprezint a tipul excep tiei, iar al doilea este op tional s i reprezint a un eventual argument. Dac a se vrea s a se stie cnd o excep tie a fost semnalata a, dar nu se inten tioneaz a tratarea ei, o form a mai simplicata a a instruc tiunii raise permite reapari tia excep tiei :
>>> 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 s i excep tii

8.5

Excep tii denite de utilizator

Un programator si poate crea propriile excep tii prin creare unei clase de excep tii noi. n mod obi snuit excep tiile pot i indirect. De exemplu : derivate din clasa Exception att nmod direct ct s
>>> 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 excep tii pot proiectate ca oricare alta clas a, dar in mod uzual ele sunt simple, deseori oferind numai un num ar de atribute, ce permit s a informeze asupra erorii ce a fost tratat a. Cnd se implementeaz a un modul care poate genera un num ar distinct de erori, se obi snuie ste s a se creeze o clasa de baz a a excep tiilor denite de acest modul, s i subclase care s a creeze clase specice pentru diferite condi tii de eroare :

8.5. Excep tii denite de utilizator

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 excep tii sunt denite cu nume care se termina n Error, similar cu denumirea excep tiilor standard. Multe module si denesc propriile excep tii pentru a raporta erorile ce pot ap area nfunc tiile denite de ele. Mai multe informa tii despre clase ve ti g asi n capitolul refclasses, Classes..

8.6

tare Denirea ac tiunilor de cura

Instruc tiunea try poate avea s i o alt a clauz a prin care se pot deni ac tiuni de cur a tare care vor executate n orice . De exemplu: circumstan ta
>>> try: ... raise KeyboardInterrupt ... finally: ... print Goodbye, world! ... Goodbye, world! Traceback (most recent call last): File "<stdin>", line 2, in ? KeyboardInterrupt

Clauza nally este executat a dac a a fost sau nu generat a o excep tie n blocul try. Cnd apare o excep tie, este regenerat a dup a ce sunt executate instruc tiunile clauzei finally. Clauza finally este de asemenea executat a la 56 Capitol 8. Erori s i excep tii

ie sire, chiar s i atunci cnd a fost apelat a o instruc tiune break sau return. Codul scris ncalauza finally este util a pentru eliberarea resurselor externe (cum ar siere sau conect ari la re tea), fara a mai vedea daca utilizarea resurse s-a ncheiat cu succes. O instruc tiune try trebuie e s a aibe una sau mai multe clauze except, e o clauz a finally, dar nu ambele n acela si timp.

tare 8.6. Denirea ac tiunilor de cura

57

58

CAPITOL

NOUA

Clase
Mecanismul de clase al limbajului Python face posibil a ad augarea de noi clase cu un minim de efort. Acest mecanism de clase este o combina tie ntre mecanismele din C++ s i Modula-3. La fel ca s i pentru module, Python nu creeaz ao barier a absolut a ntre deni tie s i utilizator, ci se bazeaz a mai mult pe polite tea utilizatorului de a nu p atrunde n deni tie. Cele mai importante facilit a ti ale claselor sunt n continuare disponibile. n terminologie C++, toate componentele unei clase( si datele membre) sunt publice, s i toate func tiile membre sunt virtuale. Nu exist a constructori sau destructori specializa ti. La fel ca n Modula-3, nu exist a scurt aturi pentru a accesa 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 func tia este apelat a. Clasele sunt n sine obiecte, iar n sens mai larg: n Python toate tipurile de date sunt obiecte, acest comportament este specic s i limbajului SmallTalk. Prin toate acestea sunt posibile importurile s i redenumirile. La fel ca n C++ s i Modula-3, tipurile predenite nu pot denite drept clase de baz a pentru eventuale extensii. De asemenea, la fel ca n C++, dar spre deosebire de Modula-3, majoritatea operatorilor cu sintax a special a(de exemplu: operatorii aritmetici) pot redeni ti n cadrul claselor.

9.1

Cteva cuvinte despre terminologie

Deoarece nu exist a o terminologie unanim recunoscut a n ceea ce prive ste clasele, nu vom folosi aici termenii din SmallTalk s i C++. Am putea folosi termenii din Modula-3, deoarece semantica acestui limbaj este mai aproape de cea a Python-ului, dar foarte pu tini utilizatori au auzit de acest limbaj, de si C++ s i SmallTalk sunt o alegere mult mai bun a, ind limbaje cu o popularitate mult mai mare. Va trebui de asemenea s a avertiz am cititorii asupra unei gre seli pe care o pot face n interpretarea celor ce urmeaz a: cuvntul obiect n Python nu nseamn a neap arat o instan tiere a unei clase. n C++, Modula-3, de asemenea s i n Python, dar nu s i n SmallTalk, exist a anumite tipuri de date care nu sunt neap arat clase: numerele ntregi s i listele nu sunt clase, dar s i alte tipuri de date mai exotice, cum sunt sierele nu sunt clase. Toate tipurile de date n Python au aproximativ acela si comportament care este mai u sor de explicat dac a ne referim la aceste tipuri de date folosind cuvntul obiect. Obiectele pot avea individualitate, sau pot avea mai multe nume(care pot servi mai multor scopuri) care s a desemneze acela si obiect. Aceast procedeu se nume ste aliasing n alte limbaje. De obicei n Python, la prima vedere, nu sunt ncurajate astfel de tehnici, care pot foarte bine ignorate cnd este vorba despre tipurile de date nemodicabile(numere, s iruri, perechi). n orice caz, tehnica aceasta, aliasing, are s i un efect inten tionat asupra sintaxei Python care prive ste obiectele alterabile (liste, dic tionare, etc.) s i obiectele ce exist a n afara contextului n care se a a programul ( siere, ferestre. etc.). Pute ti utiliza tehnica aliasing, pentru a benecia de puterea oferit a n alte limbaje, de pointeri, ntruct pute ti considera c a alias-urile func tioneaz a ntr-un anumit sens ca pointerii din C. Spre exemplu transmiterea unui obiect este mai simpl a, din moment ce se transmite doar un pointer. Dac a o func tie prime ste ca parametru un obiect pe care l modic a, cel ce a aplelat func tia va putea observa efectul func tiei, deoarece modic arile efectuate de func tie au fost f acute asupra con tinutului obiectivului s i nu asupra unui reprezent ari locale(n contextul func tiei). Explicnd toate acestea se observ a necesitatea a dou a mecanisme de transmitere a parametrilor ca n Pascal.

59

9.2
1

Domenii de vizibilitate (Scopes) s i domenii de deni tie a numelor(Name Spaces)

Deni tiile claselor manipuleaz a ntr-un mod foarte interesant domeniile de deni tie a numelor, s i o foarte bun a n telegere a modului de func tionare a domeniilor de vizibilitate s i de deni tie a numelor este foarte impotant a. n telegerea acestor mecanisme este foarte important as i se va dovedi foarte util a oric arui programator avansat Python. S a ncepem cu cteva deni tii: aceste domenii Un domeniu de deni tii a numelor este o hart a de leg aturi ntre nume s i obiecte. n momentul de fa ta sunt implementate folosind dic tionare, dar metodele de implementare pot schimbate pe viitor. Exemple de astfel de domenii sunt: domeniul numelor predenite, domeniul numelor globale dintr-un modul, domeniul numelor locale creat la apelarea unei fun tii, etc. ntr-un anumit sens atributele unui anumit obiect formeaz a un domeniu de deni tie. Un lucru foarte important de s tiut este acela c a ntre dou a nume existente n dou a domenii diferite nu exist a absolut nici o leg atur a. Din aceast a cauz a dou a module pot deni o func tie cu aceea si denumire f ar a a se creea confuzie. Un atribut este orice nume care urmeaz a unui punct, de exemplu n expresia z.real,real este un atribut al obiectului z. ntr-un sens strict, referin tele la nume denite ntr-un modul sunt de fapt referin te la atribute ale modulului: n expresia modul.func tie, modul este modulul iar func tie este un atribut al modulului. Numele globale ale modulului s i atributele modulului se a a n acela si domeniu de deni tie al numelor.(Exist ao singur a excep tie. Modulele au un atribut nemodicabil (read-only) secret: __dict__ n care se a a domeniul de deni tie al numelor ce apar tine modulului. __dict__ este un atribut dar nu este un nume global.) Atributele pot nemodicabile(read-only) sau modicabile(writeable). Atributele unui modul sunt modicabile: de genul: modul.r pute ti folosi o secven ta aspuns = 42. Atributele modicabile pot de asemenea s terse folosind operatorul del. De exemplu del modul.r aspuns va elimina atributul r aspuns din obiectul denumit modul. diferite. Domeniul Domeniile de deni tie a numelor sunt create la momente de timp diferite s i au perioade de via ta care con tine numele predenite este creat odat a cu pornirea interpretorului Python s i nu este s ters niciodat a. Domeniul numelor globale denite ntr-un modul este creat atunci cnd este nc arcat a deni tia modulului s i este distrus de obicei tot n momentul n care interpretorul este nchis. Instruc tiunile executate la primul nivel al interpretorului e dintr-un script, e interactiv, fac parte dintr-un modul numit __main__. Numele predenite se a a n domeniul __builtin__. Domeniul de deni tie a numelor pentru o func tie este creat odat a cu apelul func tiei, s i este s ters odat a cu terminarea func tiei, e prin return, e dac a acesta genereaz a o excep tie netratat a. Binen teles c a apeluri recursive genereaz a mai multe domenii de deni tie. Un domeniu de vizibilitate (scope) este o regiune a unui program Python n care un anumit domeniu de deni tie a la un nume va genera o c numelor este accesibil. Accesibil nseamn a c a o anumit a referin ta autare n domeniul de deni tie al acelui modul dspre care spunem c a este accesibil. Domeniile de vizibilitate sunt determinate static, s i sunt folosite dinamic. n timpul execu tiei exist a exact trei domenii de vizibilitate (exact trei domenii de deni tie sunt direct accesibile): primul cel mai adnc, con tine numele locale, cel de-al doilea con tine numele globale ale modulului curent, iar cel de-al treilea cel mai de sus, care este ultimul n care se caut a un nume(dac a n celelalte c autarea nu a avut succes, s i care con tine numele predenite. De obicei, cel mai adnc domeniu de vizibilitate este cel al func tiei care este executat a. n exteriorul unei func tii, acest domeniu este identic cu al doilea domeniu (cel din mijloc), n care se a a accesibile deni tiile modulului. Domeniul de vizibilitate global al unei func tii denite ntr-un modul este domeniul de deni tii al respectivului modul, indiferent de unde, sau cu ce alias este apelat a respectiva func tie. Pe de alt a parte c autarea unui anumit nume este realizat a dinamic, n timpul execu tiei. Cu toate astea deni tia limbajului evolueaz a c atre o rezolutie a numelor
1 (N.T. Traducerile celor doi termeni n limba romn a sunt improprii, iar n telegerea acestor termeni ar trebui s a e mai mult o n telegere sensului pe care o are traducerea celor doi termeni). contextual a nednd o prea mare importan ta

60

Capitol 9. Clase

static a, n timpul compil arii. n concluzie nu v a baza ti prea tare pe varianta dinamic a. Deja variabilele locale sunt determinate static. O caracteristic a a limbajului Python, aste c a atribuirile au loc n primul domeniu de vizibilitate(cel mai de jos sau cel mai adnc N.T. termenul original este innermost). Atribuirile nu realizeaz a o copiere a datelor ci leag a nume de obiecte. Acest lucru este valabil s i pentru s tergeri. Instruc tiunea del x s terge leg atura lui x din domeniul local de deni tie. De fapt toate opera tiile care introduc nume noi au impact asupra domeniului de deni tii local: instruc tiunile import sau deni tia unei func tii introduc numele modulului importat, respectiv numele func tiei n domeniul de deni tii local. Dac a este folosit a instruc tuinea global se indic a intrepretorului ca urm atorul nume s a e introdus n domeniul global.

9.3

privire asupra claselor O prima

No tiunea de clase aduce cu sine s i cteva alte no tiuni noi de sintax a, trei tipuri noi de obiecte, s i cteva no tiuni noi de semantic a.

9.3.1

Denirea unei clase

Cea mai simpl a deni tie a unei clase arat a astfel:


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

Deni tiile de clase, la fel ca deni tiile de func tii, sunt valabile de abia dup a ce sunt executate. Pute ti insera o deni tie de clas a n cadrul unei instruc tiuni if, s i clasa nu va exista dect dac a condi tia instruc tiunii if va adev arat a. n practic a, instruc tiunile din interiorul unei clase vor deni tii de func tii, dar sunt permise s i alte instruc tuni care pot de ce cunoa foarte utile uneori. Deni tiile de func tii din cadrul unei clase sunt un pic deosebite fa ta ste ti, dar despre asta vom vorbi mai trziu. Atunci cnd este introdus a deni tia unei clase noi, un nou domeniu de deni tii a numelor este creat s i folosit ca domeniu de vizibilitate local, deci toate atribuirile vor afecta noul domeniu de deni tii creat. Deni tiile de func tii vor introduce numele acelor func tii tot n acest domeniu. Cnd deni tia unei clase se termin a normal, f ar a erori, este creat un obiect nou de tipul class. Pe scurt, acest obiect con tine noul domeniu de deni tii creat odat a cu deni tia clasei. n urm atoarea sec tiune vom discuta mai mult despre obiecte de tip class. Domeniul de vizibilitate existent naintea deni tiei clasei este reactivat, s i obiectul class este introdus n respectivul domeniu de deni tii sub numele dat de numele specicat n deni tia clasei (n exemplul de mai sus: ClassName).

9.3.2

Obiecte class

Aceast a categorie de obiecte accept a dou a categorii de opera tii: referen tieri de atribute s i instan tieri. Referen tierile de atribute folosesc sintaxa standard din Python: obiect.atribut. Atribute valide sunt toate numele existente n domeniul de deni tii n momentul cre arii obiectului class. A sa c a, dac a deni tia clasei arat a astfel:

privire asupra claselor 9.3. O prima

61

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

Atunci MyClass.i s i MyClass.f sunt referin te la atribute valabile. Unul dintre atribute este un ntreg (i), iar cel alalt o metod a(f). Se pot realiza atribuiri cu atributele unei clase, deci pute ti modica valoarea atributului MyClass.i printr-o atribuire. __doc__ este de asemenea un atribut al clasei, care are valoare Un exemplu simplu de clasa. Instan tierea claselor folose ste nota tia de la func tii. Putem s a ne imagin am c a obiectul clas a este o func tie f ar a pentru respectiva clas parametrii care ntoarce ca rezultat o nou a instan ta a: Exemplul urm ator:
x = MyClass()

a clasei s creeaz a o nou a instan ta i atribuie acest obiect variabilei locale x. Opera tia de instan tiere creaz a un obiect vid. Multe clase prefer a s a creeze un obiect ntr-o stare ini tial a. Pentru a realiza acest lucru o clas a trebuie s a aib a denit a o metod a special a numit a __init__() ca n exemplul de mai jos:
def __init__(self): self.data = []

Atunci cnd o clas a are denit a metoda __init__(), instan tierea respectivei clase apeleaz a automat metoda ini __init__(). n acest fel se poate ob tine o instan ta tializat a a unei anumite clase:
x = MyClass()

Binen teles metoda __init__() poate avea argumente. n acest caz argumentele primite la instan tierea clasei sunt 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 a pute ti gndi la metoda __init__() ca la un constructor, de si nu este un constructor n toat a puterea cuvntului.

9.3.3

Obiecte instan tiate

Ce putem face cu instan tele? Singurele opera tii acceptate sunt opera tiile cu atribute. Exist a dou a tipuri de nume de atribute valide. Prima categorie: propiet a tile sau atribute de tip dat a. Aceast a categorie corespunde variabilelor instan tei n SmallTalk, s i membrilor dat a n C++, create automat atunci cnd le sunt atribuite valori. Dac a x este o instan ta a clasei MyClass urm atoarea por tiune de cod va a sa valoarea 16:

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 a este o func tie ce apar tine unui anumit obiect.(n Python termenul de metod a nu desemneaz a doar o func tie ce apar tine instan tei numai clase, adic a unui obiect; s i alte tipuri de obiecte au metode. De exemplu, obiectele list a au metodele: append, insert, sort, etc. n cele ce urmeaz a vom folosi termenul de metod a numai n sensul mai sus denit). Numele de metode disponibile pentru un anumit obiect depind de clasa din care face parte obiectul. Prin deni tie, toate atributele de tip func tie ale unei clase devin metode pentru toate instan tele respectivei clase. n exemplul nostru x.f este o metod a valabil a din moment ce MyClass.f este o func tie, n mod contrar, este evident c a x.i nu este o ntre MyClass.f s metod a. MyClass.i nu este o func tie. Exist a o diferen ta i x.f: prima este un obiect func tie iar cea de-a doua un obiect metod a(una este func tie, a doua metod a).

9.3.4

Obiecte metoda

n mod uzual o metod a este apelat a imediat:


x.f()

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

Exemplul de mai sus va apela Hello World! la innit. Ce se ntmpl a exact atunci cnd este apelat a o metod a? A ti observat c a x.f a fost apelat a f ar a nici un argument, chiar dac a n deni tia func tiei era specicat un argument. Python genereaz Ce s-a ntmplat cu argumentul? Cu siguran ta a o excep tie atunci cnd o func tie care necesit a un argument(de si poate s a nu aibe neap arat nevoie de acesta), este apelat a f ar a argumente. Probabil c a a ti ghicit deja r aspunsul: metodele au ntotdeauna ca prim parametru un obiect.n exemplul nostru apelul x.f() este absolut echivalent cu MyClass.f(x). n general a apela o metod a cu n parametrii este echivalent cu a apela func tia corespondent a insernd la nceputul listei de n argumente obiectul a c arui metod a se dore ste apelat a. Dac a nu a ti n teles nc a cum func tioneaz a metodele, o privire asupra implement arii probabil c a ar clarica lucrurile. Atunci cnd se face o referire la un atribut al unei instan te care nu este un atribut dat a, clasa din care face parte este c autat a. Dac a numele denot a un atribut existent n respectiva clas a(deci un obiect de tip func tie), este creat un obiect s metod a punnd laolalt a(mpachetnd) obiectul instan ta i obiectul func tie(tocmai g asit). n acest fel se creeaza un obiect metod a. Atunci cnd o metod a este apelat a cu o list a de argumente, obiectul metod a este despachetat, o nou a ca prim parametru. n list a de argumente este construit a ad augnd la nceputul listei de argumente obiectul instan ta cele din urm a obiectul func tie este apelat cu noua list a de argumente.

privire asupra claselor 9.3. O prima

63

9.4

Alte observa tii

Atributele dat a suprascriu atributele metod a cu acela si nume. Pentru a evita conicte de nume ce pot cauza defec tiuni greu de g asit n programe mari, este bine s a folosi ti o conven tie pentru denumiri pentru a minimiza s ansa apari tiei unor astfel de conicte. O posibil a conven tie ar scrierea numelelor de metode cu liter a ini tial a mare, prexarea numelor de atribute dat a cu un s ir de caractere mic s i unic, (poate un underscore), sau pentru metode folosi ti verbe, iar pentru propiet a ti substantive. Propiet a tile pot accesate att de metode, ct s i de utilizatorii unui anumit obiect. Cu alte cuvinte clasele nu pot folosite pentru a implementa tipuri de date abstracte. De fapt, n Python nu exist a nici un fel de mecanism de ascundere a datelor aceasta realizndu-se numai prin conven tie. (Pe de alt a parte, implementarea limbajului Python, relizat a n C, poate ascunde complet detalii de implementare controlnd accesul la datele unui obiect, dac a o astfel de abordare este necesar a). Utilizatorii unui obiect ar trebui s a manipuleze atributele dat a (propieta tile) cu aten tie orice modicare direct aa a obiectului respectiv. De notat este faptul c acestora putnd duce la o incoeren ta a utilizatorii unui obiect, pot ad auga propriile atribute dat a f ar a a afecta n vreun fel metodele, atta timp ct nu apar conicte de nume( si aici existen ta unei conven tii v a poate scuti de multe nepl aceri). Nu exist a nici o scurt atur a pentru referirea atributelor din interiorul unei metode. Acest lucru claric a codul unei metode, nemaiexistnd posibilitatea confuziei ntre variabilele locale s i variabilele instan tei. n mod conven tional, primul argument al unei metode are numele: self. Aceasta este numai o conven tie, numele self neavnd nici o semnica tie special a n Python.(Folosind aceast a conven tie codul dumneavoastr a va mai u sor de citit de c atre programatori). Orice obiect func tie ca atribut al unei clase dene ste o metod a asociat a pentru instan tele unei clase. Nu este neap arat necesar ca deni tia unei func tii s a se ae n cadrul deni tiei clasei. n acest sens se poate atribui un obiect func tie unei 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, s i h sunt toate atribute ale clasei C, s i sunt atribute func tiei, s i n mod consecvent sunt metode pentru toate instan tele clasei C. Aceast a practic a nu este indicat a, ntruct nu face dect s a ncurce cititorul programului. 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 acela si mod ca func tiile obi snuite. Domeniul global de vizibilitate asociat unei metode permite accesul la domeniul de deni tie a numelor asociat modului n care se a a denit a clasa c areia i apar tine metoda. Clasa n sine nu este folosit a niciodat a ca un domeniu global de vizibilitate. Pot g asite multe utiliz ari ale domeniului global de vizibilitate, de si unii ar putea considera inutil a existen ta acestuia.

9.5

Mo stenirea

Nu putem spune despre un limbaj c a este orientat obiect, dac a sistemul de clase nu pune la dispozi tie mecanismul de mo stenire. Sintaxa pentru mo stenire (adic a pentru crearea deni tiei unei clase derivate dintr-o clas a de baz a) este urm atoarea:
class DerivedClassName(BaseClassName): <statement-1> . . . <statement-N>

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

Atunci cnd obiectul class pentru clasa derivat a, este creat, este memorat as i clasa de baz a. Acest mecanism este folosit pentru a rezolva referirile la atribute: n caz c a un atribut nu este g asit n clasa derivat a, este c autat s i n clasa de baz a. Regula se aplic a recursiv dac a clasa de baz a este la rndul ei o clas a derivat a. Instan tierea unei clase se face la fel ca pn a acum. Dac a este apelat a o metod a a unei instan te, numele metodei este c autat nti n deni tia clasei derivate, apoi n deni tia clasei de baz a, s i a sa mai departe pn a cnd este g asit un obiect func tie corespunz ator n lan tul de mo steniri. Clasele derivate pot suprascrie metode ale clasei de baz a. Deoarece o metod a nu dispune de nici un privilegiu atunci cnd apeleaz a o alt a metod a a aceluia si obiect, o metod a a clasei de baz a care apeleaz a o alt a metod a, denit a de asemenea n clasa de baz a, poate s a apeleze de fapt o metod a suprascris a de clasa derivat a (pentru programatorii C++ putem spune c a toate metodele din Python sunt virtuale). O astfel de metod a suprascris a poate chiar s a extind a metoda de baz a, n loc de a o nlocui. Exist a o cale simpl a de a apela o metod a a clasei de baz a direct: Clas adeBaz a.metod a(self.argumente). Acest lucru poate foarte util chiar s i utilizatorilor(clien tilor) unei clase.

9.5.1

Mo stenirea multipla

Python pune la dispozi tia programatorilor s i o form a de mo stenire multipl a. O deni tie de clas a derivat a din mai multe clase de baz a arat a n felul urm ator:

9.5. Mo stenirea

65

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

Regula dup a care sunt c autate atributele este urm atoarea: dac a un atribut nu este denit n clasa derivat a atunci acesta este c autat n deni tia clasei Base1 s i n toate clasele de la care aceasta mo stene ste, apoi este c autat n Base2 s i n Base3 dup a acelea si reguli. Putem rezuma aceast a regul a n felul urm ator: nti n adncime, s i de la stnga la dreapta. (Avantajele s i dezavantajele acestei reguli pot discutate, ns a trebuie s a e foarte clar pentru toat a lumea c a o astfel de regul a este absolut necesar a, fapt sucient de evident). Este sucient de clar c a folosirea mecanismului de mo stenire multipl a va crea mari probleme de ntre tinere, deoarece n Python conictele ce pot ap area ntre nume sunt evitate numai prin conven tii. O problem a cunoscut a apare atunci cnd o clas a mo stene ste de la dou a clase care la rndul lor sunt derivate dintr-o singur a clas a. De si este destul de simplu s a ne imagin am ce se va ntmpla n acest caz, nu este clar c a regulile vor de folos pentru claricarea situa tiei.

9.6

Variabile private

Exist a un suport limitat pentru identicatorii clselor private. Orice identicator de forma __spam (cel pu tin dou a underscore nainte, cel mult un underscore dup a) este acum textual nlocuit cu _cla a__spam, unde clas a este suprimate. Mutilarea este realizat numele curent al clasei cu underscor-urile din fa ta a fara o analiza a pozi tiei sintactice a identicatorului, a sa nc at putnd folosit a la denirea unei instan tieri a unei clase private s i a variabilelor s i metodelor clasei ca globale, s i la memorarea instan tierii variabilelor private naceast a clas a la instan tierea altei clase. O trunchere a numelui poate ap area cnd acesta este mai lung de 255 de caractere. n afara claselor, sau cnd numele clasei este alc atuit numai din underscor-uri nu se face eliminarea underscor_urilor. Acest mecanism pune la dispozi tia programatorului o metod a foarte facil a de a crea atribute private, f ar a a- si face griji c a aceste atribute pot provoca conicte de nume. Toate acestea sunt realizate n Python pentru a preveni eventualele erori, totu si, este n continuare posibil a modicarea atributelor private, ceea ce se poate dovedi foarte util n anumite cazuri ca de exemplu la depanare. ( Observatie : o clas a derivat a care are acela si nume cu clasa de baz a poate folosi variabilele private ale clasei de baz a). Observa ti c a, codul ce este trimis instruc tiunilor exec, eval() sau evalfile() nu ia n considerare numele clasei care realizeaz a invoc arile, acest efect ind similar celui realizat prin instruc tiuni global, efect ce nu poate ob tinut pentru cod compilat. Aceea si restric tie se aplic as i pentru getattr(), setattr() s i delattr(), de asemenea s i pentru accesarea direct a a dic tionarului __dict__. Iat a un exemplu de clase care implementeaz a propriile metode __getattr__() s i __setattr__(), s i stocheaz 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 a, poate foarte util s a putem crea tipuri de date similare celei record din Pascal, sau struct din C, tipuri de date care s a adune la un loc mai multe date de diferite tipuri. Pentru a realiza acest lucru pute ti folosi clasele. O 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 a construim un alt scenariu: presupunnd c a ave ti o func tie care prelucreaz a anumite date dintr-un obiect sier, pute ti s a deni ti o clas a cu metodele read() s i readline() care s a citesc a informa tii dintr-un s ir de caractere n loc de un sier. Metodele obiectelor au de asemenea atribute: metod a.im__self reprezint a obiectul de care apar tine metoda specicat a, iar metod a.im__func reprezint a func tia corespunz atoare metodei.

9.7.1

Excep tiile pot clase

Excep tiile denite de utilizator pot att obiecte de tip string, ct s i clase. Folosind clasele pentru a deni excep tii, pute ti crea o ntreag a ierarhie de excep tii care poate foarte u sor extins a. Exist a o alt a form a a insruc tiunii raise:
raise Class, instance raise instance

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

O clauz a except poate a sa att excep tii de tip clas a, ct s i de tip s ir de caractere. Urm atorul exemplu va a sa B, C, D n aceast a ordine:

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 a dac a ordinea clauzelor except ar fost invers a, (cu except B la nceput), exemplul ar a sat B, B, B; deoarece clasa B este clasa din care sunt derivate clasele C s i D. Cnd un mesaj de eroare este a sat pentru o excep tie netratat a ce provine dintr-o clas a, numele clasei este de asemenea a sat.

68

Capitol 9. Clase

CAPITOL

ZECE

Continuarea?
S a sper am c a acest tutorial v-a trezit interesul n ceea ce prive ste limbajul Python. Ce ar trebui s a face ti de acum ncolo? Ar trebui s a citi ti, sau cel pu tin s a r asfoi ti Python Library Reference,document ce explic a foarte detaliat ecare func tie, tip de date, modul, etc. existent n Python. Distribu tia standard de Python con tine o cantitate imens a de cod scris att n C, ct s i n Python, exist a module UNIX ce pot folosite pentru a citi c asu tele de po st a electronic a, module care faciliteaz a lucrul cu protocolul HTTP, module pentru generarea numerelor aleatoare, etc. Un site foarte util este http://www.python.org. Aici exist a documenta tii buc a ti de cod scrise de al ti programatori s i link-uri legate de Python. Copii ale acestui site exist a pe serverele din ntreaga lume (Europa, Australia, Japonia, etc). n func tie de locul n care v a aa ti, pentru o vitez a de acces mai mare, pute ti folosi una dintre aceste copii. Un alt site ce se poate dovedi foarte util este http://starship.python.net. Pentru ntreb ari sau raportarea anumitor probleme pute ti folosi grupul comp.lang.python, sau pute ti scrie la Pythonlist@python.org. n ecare zi sunt puse n jur de 120 de ntreb ari care, de obicei, si g asesc r aspunsul. nainte de a pune o ntrebare, verica ti lista ntreb arilor puse frecvent (Freqvently Asked Questions = FAQ) care poate g asit a la adresa http://www.python.org/doc/faq.html. R aspunsurile de la aceast a adres a, la diferite ntreb ari puse de al ti programatori, v a pot ajuta de foarte multe ori n rezolvarea problemelor dumneavoastr a.

69

70

ANEXA

s Editarea n linie de comanda i repetarea comenzilor anterioare


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

A.1 Editarea n linie de comanda


Dac a este suportat a, aceast a facilitate va disponibil a atunci cnd interpretorul a seaz a promptul principal sau cel secundar. Linia curent a poate editat a folosind caracterele de control conven tionale Emacs. Cele mai importante sunt: C-A(Control-A) mut a cursorul la nceputul liniei; C-E(Control-E) mut a cursorul la sfr situl liniei; C-B mut a cursorul cu o pozi tie la stnga; C-F mut a cursorul cu o pozi tie la dreapta; BACKSPACE s terge caracterul de la stnga cursorului; C-D s terge caracterul de la dreapta cursorului; C-K s terge tot ce urmez a pe linie n dreapta cursorului; C-Y reface ultimul s ir s ters cu C-K; C-_ anuleaz a ultima comand a efectuat a. Opera tia poate repetat a.

A.2 Repetarea comenzilor anterioare(History)


Toate comenzile executate sunt salvate ntr-o zon a tampon (Buffer). Atunci cnd este executat a o nou a instruc tiune aceasta este salvat a la sfr situl buffer-ului. 71

C-P revine la o comand a anterioar a n buffer celei executate. C-M nainteaz a la urm atoarea instruc tiune din buffer. Orice linie din buffer poate modicat a. Dac a o linie a fost modicat a ve ti vedea un caracter * n fa ta acesteia care ndic a c a a fost modicat a. O instruc tiune din buffer este executat a dac a se apas a, evident, ENTER. C-R porne ste o c autare incremental a n buffer n sens invers. C-S porne ste o c autare n sens normal.

A.3 Redenirea tastelor func tionale


Tastele func tionale s i al ti parametrii ai bibliotecii Readline, pot redeni ti prin modicarea sierului /.inputrc. Pentru a redeni func tia unei combina tii de taste trebuie folosit a sintaxa: tast a:func tie sau sir de caractere:func tie. O op tiune poate setat a folosind set op tiune valoarenou a. Iat a un exemplu:
# 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 func tie pentru Tab este aceea de a insera Tab, nu func tia de completare Readline. Dac a se dore ste ns a utilizarea sa n func tia de completare se va pune :
Tab: complete

n /.inputrc. (Bine n teles c a acum va mai dicil de a scrie spa tiile de aliniere) Completarea automat a a numelui unei variabile, sau a unui modul, este op tional a. Pentru a o activa n modul de lucru interactiv ad auga t n sierul de startup urm atoarele :1
import rlcompleter, readline readline.parse_and_bind(tab: complete)

Aceasta leag a tasta Tab de func tia de completare, deci ap asnd tasta Tab de doua ori activeaz a completarea; analizeaz a numele instruc tiunii Python, variabilele locale curente s i numele de module disponibile.Pentru expresiile cu punct de tipul string.a, evalueaz a expresia pn a la nal, dup a . s i apoi sugereaz a completarea dat a de atributele obiectelor rezultate. De re tinut c a se poate executa codul unei aplica tii denite dac a un obiect ce are metoda __getattr__() face parte din expresie. Un sier startup mai cuprinz ator poate ar ata ca n exemplul urm ator. De notat c a el i si sterge numele pe care le creaz a n momentul n care nu-i mai sunt necesare. Acest lucru se petrece cnd sierul de starup se execut a n acela si domeniu de deni tie ca s i comenzile interactive, iar eliminarea numelor evit a generarea unor efecte colaterale n mediul interactiv.
1

Python va executa con tinutul unui sier identicat prin variabila de mediu PYTHONSTARTUP n momentul pornirii interpretorului interactiv.

72

s Anexa A. Editarea n linie de comanda i repetarea comenzilor anterioare

Pute ti g asi acest lucru convenabil pentru a p astra cteva module importate, cum ar os, s i care se dovedesc necesare 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 facilit a ti reprezint a un pas enorm comparativ cu versiunile anterioare ale interpretorului; oricum au r amas cteva deziderate nemplinite : ar frumos ca s a e sugerat un alineat corect la continuarea unei linii (analizorul sintactic s tie dac se va cere un alineat). Acest nou mecanism ar putea utiliza tabela de simboluri a interpretorului. Util ar s i un mecanism care s a verice (sau s a sugereze) potrivirea parantezelor, ghilimelelor, etc.

A.4. Comentarii

73

74

ANEXA

otanta: rezultate s Aritmetica n virgula i limitari


Numerele n virgul a otant a sunt reprezentate n hardware-ul calculatorului ca frac tii n baza 2 (binare). De exemplu, frac tia zecimal a
0.125

are valoarea 1/10 + 2/100 + 5/1000, s i n acela si fel frac tia binar a
0.001

real are valoarea 0/2 + 0/4 + 1/8. Aceste dou a frac tii au aceea si valoare, singura diferen ta a ind c a prima este scris a n baza 10, iar a doua n baza 2. Din p acate majoritatea frac tiilor zecimale nu pot reprezentate corect ca frac tii binare. O prim a concluzie este c a, (n general, numerele n virgul a otant a zecimal a pe care le introduce ti au numai o reprezentare aproximativ a prin numerele n virgul a otant a binar a memorate n calculator. Problema este u sor de n teles nt n baza 10. S a consider am frac tia 1/3. O pute t aproxima cu o frac tie baza 10:
0.3

sau, mai precis,


0.33

sau , si mai precis,


0.333

s i tot a sa. Nu conteaz a ce num ar de digi ti ve ti scrie, rezultatul nu va nicicd exact 1/3, dar cre ste acurate tea aproxim arii lui 1/3. n acela si mod, nu conteaz a cti digi ti n baza 2 folosi ti, valoarea zecimal a 0.1 nu va reprezentat a exact niciodat a printr-o frac tie. n baza 2, 1/10 este o frac tie care se repet a la innit
0.0001100110011001100110011001100110011001100110011...

Oprirea la un num ar nit de bi ti d a o aproximare. Iat a ce se a seaz a n situa tia urm atoare :

75

>>> 0.1 0.10000000000000001

Pe majoritatea ma sinilor existente ast azi acest rezultat se a seaz a dac a introduce ti 0.1 la prompterului Python-ului. Se ntmpl a a sa pentru c a num arul de bi ti utiliza ti de hardware s a mememoreze valoarea n virgul a otant a variaz a de la o ma sin a la alta, iar Python listeaz a doar o aproxima tie zecimal a a valorii zecimale reale a aproxima tiei binare memorat a n ma sin a. Pe majoritatea ma sinilor, dac a Python va tip ari valoarea zecimal a real a a aproxima tiei binare memorate pentru 0.1, va a sa
>>> 0.1 0.1000000000000000055511151231257827021181583404541015625

Prompterul Python utilizeaz a func tia implicit a repr() ca s a ob tin a o versiune de s ir pentru toate obiectele pe care le a seaz a. n cazul numerele otante repr(oat) rotunje ste valoarea zecimal a la 17 digi ti semnicativi, astfel
0.10000000000000001

repr(oat) folose ste 17 bi ti semnicativi pentru c a sunt considera ti sucien ti pe majoritatea ma sinilor, a sa c a rela tia eval(repr(x)) == x este exact a pentru toate numerele otante nite x, dar rotunjirea la 16 bi ti nu este sucient a pentru a face rela tia adev arat a. Acesta este un lucru normal al aritmeticii binare n virgul a otant a : nu este un bug Python, nici un bug al codului dumneavoastr as i ve ti constata o astfel de anomalie n toate limbajele care folosesc aritmetica n virgul a otant a oferit a de hardware (unele limbaje pot s a nu a seze implicit diferen ta) Func tia intern a Python str() genereaz a numai 12 digi ti semnicativi s i poate c a dori ti s a o folosi ti modicat a. Este des utilizat a func tia eval(str(x)) pentru a-l ob tine pe x, dar este mai placut s a se a seze :
>>> print str(0.1) 0.1

E bine de s tiut c a, n sens real, este o iluzie : n ma sin a valoarea nu este exact 1/10, valoarea adev arat a din ma sin a este rotunjit a la a sare. Aceast a surpriz a este urmata de altele. De exemplu dup a ce se a seaz a
>>> 0.1 0.10000000000000001

apare tenta tia s a utiliza ti func tia round() ca s a trunchia ti iar as i la un digit. Dar aceasta nu face nimic:
>>> round(0.1, 1) 0.10000000000000001

Problema este c a valoarea memorat a nvirgul a otant a binar a pentru "0.1" a fost f acut a n cea mai bun a aproximare binar a posibil a la 1/10, deci orice alt a rotunjire ulterioar a nu o poate face mai bine : a fost dat a deja cea mai bun a solu tie. a faptului c Alt a consecin ta a 0.1 nu este exact 1/10 este aceea c a ad augnd la 0.1 pe el nsu si de 10 ori nu se ob tine 1.0:

76

otanta: rezultate s Anexa B. Aritmetica n virgula i limitari

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

Aritmetica binar a n virgul a otant a are multe surprize de acest gen. Problema cu "0.1" este explicat a n sec tiunea urm atoare, "Erori de reprezentare". Vezi : The Perils of Floating Point privind tratarea complet a a altor surprize de acest gen. Cum s-ar spune la sfr sit: "nu este u sor de r aspuns". Totu si nu dispera ti din cauza rgulei otante! Erorile opera tiilor de otant a din Python sunt mo stenite de la virgula otant a a hardware-ului s i la majoritatea ma sinilor sunt de un ordin mai mic de 1/2**53 pe opera tie. Acestea sunt mai mult dect acceptabile pentru cele mai multe aplica tii, dar trebuie s a re tine ti c a nu sunt datorate aritmeticii zecimale s i c a la ecare opera tie nvirgul a otant a apare o eroare de rotunjire. Pn a la apari tia unor cazuri patologice, pentru cele mai multe situa tii de utilizare a aritmeticii nvirgul a otant a se ob tin rezultatele a steptate, dac a pur s i simplu se rotunje ste rezultatul nal a sat la num arul de zecimale dorit. Uzual func tia str() este sucient a, iar pentru un control mai riguros a se vedea discu tia despre operatorul de format % : formatele %g, %f s i %e sunt moduri exibile s i u soare pentru a sarea rezultatelor.

B.1

Erori de reprezentare

Sec tiunea explic a ndetaliu exemplul "0.1" s i arat a cum se poate face o analiz a exact a a cazurilor. n principal se urm are ste familiarizarea cu reprezentarea binar a n virgul a oant a. Eroarea de reprezentare se refer a la faptul c a frac tiile zecimale nu se pot reprezenta exact ca frac tii binare (n baza 2). Acesta este motivul major pentru care Python (sau Perl, C, C++,Java, Fortran, s i multe altele) nu a seaz a valoarea exact a a num arului zecimal pe care-l a stepta ti :
>>> 0.1 0.10000000000000001

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

ca
J ~= 2**N / 10

s i reapelnd J are exact 53 de bi ti (este >= 2**52 dar < 2**53), s i cea mai bun a valoare pentru N este 56:

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 a J cu exact 53 de bi ti. Atunci cea mai bun a valoare posibil a pentru J este ctul rotunjit:
>>> q, r = divmod(2L**56, 10) >>> r 6L

Dup a ce restul este mai mare dect jum atatea lui 10, cea mai bun a aproxima tie se ob tine prin rotunjirea:
>>> q+1 7205759403792794L

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

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

Dac a se nmul te ste frac tia cu 10**30, vom vedea valoarea (truncheat a) a celor mai semnicativi 30 de digi ti zecimali ai s ai:
>>> 7205759403792794L * 10L**30 / 2L**56 100000000000000005551115123125L

nsemnnd c a num arul exact memorat n calculator este aproximativ egal cu valoarea zecimal a 0.100000000000000005551115123125. Rotunjind la 17 digi ti semnicativi rezult a 0.100000000000000001 pe care Python l a seaz a (va a sa pe orice platform a conform a 754 care va face tot posibilul s a converteasc a intrare s i ie sire prin biblioteca C proprie al dumneavoastr a s-ar putea s a nu reu seasc a acest lucru!)

78

otanta: rezultate s Anexa B. Aritmetica n virgula i limitari

ANEXA

Istoria s i licen ta
C.1 Istoricul produsului Python

Python a fost creat la nceputul anilor 1990 de c atre Guido van Rossum la Stichting Mathematisch Centrum (CWI, vezi http://www.cwi.nl/) din Olanda, ca succesor al limbajului ABC. Guido a r amas principalul autor al Pythonului, care acumuleaz a multe contribu tii ale altora. n 1995 Guido i si continu a munca la Python la Corporation for National Research Initiatives (CNRI, vezi http: //www.cnri.reston.va.us/) n Reston, Virginia, unde a lansat cteva versiuni ale software-ului. n mai 2000, Guido s i 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 na stere Python Software Foundation (PSF, vezi http://www.python.org/ psf/) o organiza tie non prot creat a special pentru a de tne drepturile de autor1 referitoare la Python. Digital Creations este unul din sponsorii PSF. Toate lans arile2 Python sunt Open Source (vezi http://www.opensource.org/ pentru a g asi deni tia Open Source ). Istorice ste vorbind cele mai multe dintre lans arile Python, nu toate, sunt de asemenea compatibile GPL(General Public License). Tabelul urm ator face un sumar al diferitelor lans ari. 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 a: Compatibil GPL nu nseamn a c a Python este distribuit sub GPL. Toate licen tele Python, spre deosebire de GPL, i ti permit s a distribui o versiune modicat a f ar a a- ti face s i modic arile open source. Licen tele compatibile GPL fac posibil a combinarea Pyton-ului cu alte software care au ap arut sub GPL; celelate neputnd face acest lucru. Mul tumim acelor voluntari numero si din exteriorul echipei, care lucrnd sub coordonarea lui Guido au f acut posibile aceste lans ai.
1 Intellectual 2 N.T.

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

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 s i licen ta

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 s i licen ta

S-ar putea să vă placă și