Sunteți pe pagina 1din 109

Tutorial Python

Versiunea 2.4.1

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

12 August 2005

Python Software Foundation Email: docs@python.org

Copyright 2001-2004 Python Software Foundation. All rights reserved. Copyright 2000 BeOpen.com. All rights reserved. Copyright 1995-2000 Corporation for National Research Initiatives. All rights reserved. Copyright 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 puternice 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 biblioteca standard sunt oferite sub form a de surse sau compilate pentru majoritatea plati pot distribuite gratuit. Pe acela si site formelor existente, pe site-ul Python, http://www.python.org/, s 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 biblioteci incluse n distribu tia Python, descrise n documentul Python Library Reference.

CUPRINS

1 2

De ce Python ? Utilizarea interpretorului Python 2.1 Invocarea interpretorului . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Interpretorul s i mediul n care ruleaz a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . O scurt a introducere n Python 3.1 Utilizarea Python-ului drept calculator de birou . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Primii pa si n programare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Structuri de control 4.1 Instruc tiunea if . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Instruc tiunea for . . . . . . . . . . . . . . . . . . . . . . . . . 4.3 Func tia range() . . . . . . . . . . . . . . . . . . . . . . . . . 4.4 Instruc tiunile break s i continue, s i clauze else pentru bucle 4.5 Instruc tiunea pass . . . . . . . . . . . . . . . . . . . . . . . . 4.6 Denirea func tiilor . . . . . . . . . . . . . . . . . . . . . . . . 4.7 Mai multe despre denirea func tiilor . . . . . . . . . . . . . . . Structuri de date 5.1 Mai multe despre liste . . . . . . . 5.2 Instruc tiunea del . . . . . . . . . 5.3 Perechi s i secven te . . . . . . . . . 5.4 Seturi . . . . . . . . . . . . . . . . 5.5 Dic tionare . . . . . . . . . . . . . 5.6 Tehnici de parcurgere a secven telor 5.7 Mai multe despre condi tii . . . . . 5.8 Compararea secven telor . . . . . . Module 6.1 Mai multe despre module 6.2 Module standard . . . . . 6.3 Func tia dir() . . . . . 6.4 Pachete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1 3 3 4 7 7 16 19 19 19 20 20 21 21 23 27 27 31 31 32 33 34 35 36 37 38 39 40 41 45 45 47 51 51 51 52 54

Intr ari s i ie siri 7.1 Formatarea elegant a a datelor de ie sire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.2 Citirea s i scrierea sierelor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Erori s i excep tii 8.1 Erori de sintax a . . . 8.2 Excep tii . . . . . . . 8.3 Tratarea excep tiilor . 8.4 Generarea excep tiilor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8.5 8.6 9

Excep tii denite de utilizator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Denirea ac tiunilor de cur a tare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

54 56 57 57 58 59 61 62 64 64 65 65 67 67 69 69 69 70 70 70 71 71 71 72 72 73 73 75 75 76 77 77 78 79 79 80 83

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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.8 Excep tiile pot clase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.9 Iteratori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.10 Generatori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.11 Expresii generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

10 Pe scurt despre Standard Library - partea I 10.1 Interfa ta cu sistemul de operare . . . . . . . . . . . . . . . . . . . 10.2 Fi sierele Wildcard (asterisc) . . . . . . . . . . . . . . . . . . . . . 10.3 Argumentele n linia de comand a . . . . . . . . . . . . . . . . . . 10.4 Redirectarea semnal arii erorilor s i terminarea execu tiei programului 10.5 Unicarea trat arii s irurilor . . . . . . . . . . . . . . . . . . . . . . 10.6 Module matematice . . . . . . . . . . . . . . . . . . . . . . . . . 10.7 Accesul la Internet . . . . . . . . . . . . . . . . . . . . . . . . . . 10.8 Data s i timpul . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.9 Compresarea datelor . . . . . . . . . . . . . . . . . . . . . . . . . 10.10 M asurarea performan tei . . . . . . . . . . . . . . . . . . . . . . . 10.11 Controlul calit a tii programului . . . . . . . . . . . . . . . . . . . 10.12 Python oferit "la cheie" . . . . . . . . . . . . . . . . . . . . . . . 11 Pe scurt despre Standard Library - partea II 11.1 Formatarea datelor de ie sire . . . . . . . 11.2 Sirurile s ablon (Templating) . . . . . . . 11.3 Lucrul cu reprezent ari binare ale datelor 11.4 Multi-threading . . . . . . . . . . . . . 11.5 Conectivitatea (Logging) . . . . . . . . 11.6 Leg aturi slabe la memorie . . . . . . . . 11.7 Instrumente de lucru cu listele . . . . . . 11.8 Aritmetica n virgul a otant a zecimal a . 12 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

85 85 85 86 87 89 91 93 93 94 96

B Aritmetica n virgul a otant a: rezultate s i limit ari B.1 Erori de reprezentare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C Istoricul produsului Python s i licen tierea C.1 Istoricul produsului . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.2 Terms and conditions for accessing or otherwise using Python . . . . . . . . . . . . . . . . . . . C.3 Licenses and Acknowledgements for Incorporated Software . . . . . . . . . . . . . . . . . . . .

ii

CAPITOLUL

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 scriere - compilare - 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 u sor de folosit 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 format binar (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. 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 1

nu numai c a sunt permise, sunt chiar ncurajate! 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.

Capitolul 1. De ce Python ?

CAPITOLUL

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. 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 comand a [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 cel mai 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 parametrul -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, acestia vor transmi si mai departe script-ului prin intermediul variabilei sys.argv, variabil a 3

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 n care 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
2.2.1

Interpretorul s i mediul n care ruleaza


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 ao 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

(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. Scriptul poate f acut executabil utilizd comanda chmod :

Capitolul 2. Utilizarea interpretorului Python

$ chmod +x myscript.py

2.2.3

Codicarea codului sursa

n sierele surs a Python se pot utiliza s i alte codic ari in afar a de ASCII.Pentru a realiza acest lucru cel mai bine este s a pune ti imediat dupa #! nc a un caracter de comentariu de linie p[entru a deni codicarea sierului surs a:
# -*- coding: \code{encoding} -*-

Dupa aceast a declara tie toate caracterele din codul surs a vor tratate ca ind codicate in encoding si este posibil s a se scrie s iruri de caractere Unicode direct in codicarea aleasa. Lista posibilelor codic ari o pute ti g asi in Python Library Reference, sec tiunea codecs. De exemplu, pentru a scrie cu caractere Unicode ce includ simbolul valutar Euro, se poate utiliza codicarea ISO-8859-15, cu valoarea 164 pentru simbolul valutar Euro. Acest script va tip ari valoarea 8364 (codul Unicode pentru simbolul Euro) si apoi iese :
# -*- coding: iso-8859-15 -*currency = u" " print ord(currency)

Daca editorul folosit poate salva sierul in format UTF-8 cu un UTF-8 byte order mark (aka BOM) pute ti folosi acest lucru in locul unei declaratii de codicare. IDLE accepta aceast a posibilitate daca se seteaz a Option/General/Default Sorce Encoding/UTF-8. Observa tie: Acest lucru nu este recunoscut de versiunile Python mai vechi de 2.2, precum si de sistemele de operare cu sierele script ce incep cu #! (sistemele UNIX). Utilizd UTF-8 (cu declaratie de codicare, sau direct), caracterele utilizate se multitudinea de limbi de de glob pot ap area simultan in s iruri literale s i comentarii. Nu este acceptat a utilizarea caracterelor non ASCII pentru numele de identicatori. Pentru a reprezenta corect caracterele, editorul cu care lucrati ar trebui s a recunoasc a c a un sier este scris n UTF-8, s i trebuie s a foloseasc a un font care s a con tina toate caracterele din ssier.

2.2.4

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:

2.2. Interpretorul s i mediul n care ruleaza

import os filename = os.environ.get(PYTHONSTARTUP) if filename and os.path.isfile(filename): execfile(filename)

Capitolul 2. Utilizarea interpretorului Python

CAPITOLUL

TREI

introducere n Python O 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 sunt linii de ie prompt. Liniile care nu 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

# si al doilea comentariu # ... si 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 aceiasi 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 si 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):

introducere n Python Capitolul 3. O 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 variabila implicit a_s i comportamentul s au extraordinar.

3.1. Utilizarea Python-ului drept calculator de birou

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 sir de caractere mai lung,\n\ care se intinde pe mai mai multe linii, exact ca in 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 sir de caractere mai lung, care se intinde pe mai mai multe linii, exact ca in 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 backsleshul 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 sir de caractere mai lung,\n\ care se intinde pe mai mai multe linii, exact ca in C." print hello

va tipari:
Acesta este un sir de caractere mai lung,\n\ care se intinde pe mai mai multe linii, exact ca in 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:

10

introducere n Python Capitolul 3. O scurta

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

# # #

<<<-

Corect Corect Incorect

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

3.1. Utilizarea Python-ului drept calculator de birou

11

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 sirul inafara 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:
>>> 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 inafara de ultimele doua caractere

Dar, aten tie -0 este acela si lucru cu 0, si nu se numara de la dreapta!

12

introducere n Python Capitolul 3. O scurta

>>> 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 a s 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

Vede ti s i : Tipurile secven ta (../lib/typesseq.html) Sirurile si s irurile Unicode descrise n sectiunea urm atoare sunt exemple ale tipului secven t as i suport a opera tiunile obi snuite pentru acest tip. Metodele aplicabile s irurilor (../lib/string-methods.html) Att sirurilor simple, ct s i Unicode li se pot aplica un num ar mare de metode pentru transformare s i c autare. Opera tii de formatare a s irurilor (../lib/typesseq-strings.html) Opera tiile de formatare invocate, cnd s irurile obi snuite sau Unicode sunt in stnga operatorului %, sunt descrise mai n detaliu aici.

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. 3.1. Utilizarea Python-ului drept calculator de birou 13

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 (scriere usual a : i18n i + 18 characters + n). Unicode rezolv a aceste probleme asocind o singur a pagin a tuturor script-urilor. 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 ghilimelelor 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 n s ir caractere speciale, o pute ti face foarte simplu folosind codarea Python Unicode-Escape. Iat a un exemplu:
>>> uHello\u0020World ! uHello World !

Secven ta escape \u0020 indic a interpretorului s a insereze caracterul cu ordinalul 0x0020 (caracterul spa tiu) npozi tia precizat a. Alte caractere sunt utilizate folosind direct valoarea ordinalului s au ca ordinal Unicode. Datorit a ri faptului c a primele 256 de caractere Unicode sunt acelea si ca s i n nota tia standard Latin-1, folosit a n multe ta occidentale, procesul de introducere a caracterelor Unicode devine mult mai simplu. Pentru exper ti exist as i un mod brut (raw-mode) identic cu cel utilizat pentru s irurile normale. naintea ghilimelelor 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 !

Mod raw poate foarte util dac a ave ti de introdus un num ar mare de backslash-uri. n afar a de metodele de codare standard, Python ofer a multe alte metode de a crea s iruri Unicode, pe baza cod arilor cunoscute. Func tia predenit a unicode() permite accesarea tuturor CODEC-urilor Unicode (CODEC = COder & DECoder). Cteva dintre codic arile foarte cunoscute ale caror CODEC-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 semnaliznd 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.
>>> 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.

14

introducere n Python Capitolul 3. O scurta

>>> 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!]

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 :

3.1. Utilizarea Python-ului drept calculator de birou

15

>>> # 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] # Vezi sectiunea 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.

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:

16

introducere n Python Capitolul 3. O scurta

>>> ... ... >>> ... ... ... 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 lungime diferit de list a, 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 cu 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:
>>> 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.

3.2. Primii pa si n programare

17

18

CAPITOLUL

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 tiunea if

Poate c a cea mai cunoscut a instruc tiune de control este instruc tiunea if. Exemplu:
>>> >>> ... ... ... ... ... ... ... ... ... x = int(raw_input("Introduceti un numar intreg : ")) if x < 0: x = 0 print Negativul schimbat in zero 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 prescurtarea de la elseif, s i este folositor pentru a evita tabularea excesiv a. O secven ta if..elif..elif func tioneaz a ca un bloc case sau switch, secven te proprii altor limbaje .

4.2

Instruc tiunea 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).
>>> # Masoara marimea unor siruri ... 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 secven telor modicabile, cum ar listele). Dac a apare necesitatea de a modica secven ta n timpul itera tiei, 19

itera tia trebuie s a e asociat a unei copii a secven tei. Nota tia subsecven telor 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 con tin 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 ncepnd cu un alt num range() 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:
>>> 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 tiunile 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:

20

Capitolul 4. Structuri de control

>>> 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 fara sa gaseasca 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 tiunea 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.6

Denirea func tiilor

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 sirul lui Fibonacci pana la n "Scrie sirul lui Fibonacci pana la n" a, b = 0, 1 while b < n: print b, a, b = b, a+b # Folosim functia 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, n parantez a, o list a de parametrii. Instruc tiunile care formeaz a func tia ncep pe linia imediat urm atoare s i trebuie de margine. Prima instruc s a e distan tate mai mult dect antetul func tiei fa ta tiune din corpul func tiei poate , op tional, un s ir de caractere. 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

4.5. Instruc tiunea pass

21

instruc tiunea global. Parametrii actuali ai unei func tii apelate sunt introdu si n tabela de simboluri local a a acelei func tii n momentul apel arii ei. Astfel transferul argumentelor se face utiliznd apelul 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 n C, 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:
>>> 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 sirul lui Fibonacci pana la n "Intoarce o lista continand sirul 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 functiei 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.
1 De fapt apelul prin referin ta poate mai bine n teles daca este transmis un obiect modicabil s i apelantul va vedea dac a n urma apelarii obiectul s-a modicat ( ex.: un element inserat ntr-o list a).

22

Capitolul 4. Structuri de control

4.7

Mai multe despre denirea func tiilor

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:
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 ?) sau: ask_ok(Dori ti s a sterge ti fi sierul ?, 2) 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, cum este lista, dic tionarul, sau instan tierea unei clase. 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:

4.7. Mai multe despre denirea func tiilor

23

def f(a, L=None): if L is None: L = [] L.append(a) return L

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 voltage parrot(voltage=5.0, mort) # Dupa cuvantul cheie trebuie sa urmeze un argument tip cheie parrot(110, voltage=220) # Doua valori atribuite aceleiasi 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:

24

Capitolul 4. Structuri de control

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:


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

Dspachetarea listelor de argumente

Situ tia invers a este aceea n care argumentele se g asesc deja ntr-o list a sau pereche, dar este necesar a despachetarea lor pentru apelarea unei func tii care necesit a argumente separate pozi tional. De exemplu, functia interna range() necesita parametrii separa ti pentru start s i stop. Dac a argumentele nu sunt transmise separat, scrie ti apelarea func tiei folosind operatorul * pentru despachetarea argumentelor dintr-o list a sau dintr-o pereche :
>>> [3, >>> >>> [3, range(3, 6) 4, 5] args = [3, 6] range(*args) 4, 5] # apelare normala

# apelare cu despachetarea argumentelor dintr-o lista

4.7.5

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.

4.7. Mai multe despre denirea func tiilor

25

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.6

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. 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!

26

Capitolul 4. Structuri de control

CAPITOLUL

CINCI

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

27

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

28

Capitolul 5. Structuri 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(). ), ntoarce o secven format Func tia filter(), cu sintaxa filter(func tie, secven ta 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]

), apeleaz Func tia map(), cu sintaxa map(func tie, secven ta a func tia specicat a ca parametru pentru , s ecare element din secven ta i ntoarce o nou a list a format a din rezultatele ntoarse de func tie. Pentru a calcula similar p atratele 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() poate accepta ca parametrii mai multe secven te. n acest caz func tia transmis a ca parametru trebuie s a e modicat a corespunz ator, astfel nct 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 func tiei map() None, 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)]

Func tia reduce(func tie, secven t a) ntoarce o valoare simpl a care este calculat a n felul urm ator: este apelat a func tia (obligatoriu o func tie binar a care 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. Exemplul de mai jos calculeaz a suma primelor numere naturale:

5.1. Mai multe despre liste

29

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

va returnat Dac a exist a un singur element n secven ta a valoarea acestuia. 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:
>>> 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]]

30

Capitolul 5. Structuri de date

>>> [x, x**2 for x in vec] File "<stdin>", line 1, in ? [x, x**2 for x in vec] ^ SyntaxError: invalid syntax

# error - parens required for tuples

>>> [(x, x**2) for x in vec] [(2, 4), (4, 16), (6, 36)]

>>> vec1 = [2, 4, 6] >>> [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]

Instruc tiunea 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.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 . Deoarece Python este un s i pozi tionarea (slicing). Sirurile s i listele sunt dou a exemple de tipuri de date secven ta . Exist limbaj 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:
1

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

5.2. Instruc tiunea del

31

>>> 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 orice fel de secven ta

5.4

Seturi

Limbajul Python are s i un tip de date pentru seturi. Un set este o colec tie neordonat a de elemente unice (f ara duplicate). Esen ta ei const a n testarea membrilor s i eliminarea duplicatelor. Obiectele de tip set suport a, de asemenea, opera tii matematice ca : uniunea, intersec tia, diferen ta s i diferen ta simetric a. Iat a o scurt a demonstra tie :

32

Capitolul 5. Structuri de date

>>> basket = [apple, orange, apple, pear, orange, banana] >>> fruits = set(basket) # creaza un set fara duplicate >>> fruits set([orange, pear, apple, banana]) >>> orange in fruits # testarea rapida a membrilor True >>> crabgrass in fruits False >>> # Dmonstrarea operatiilor set pentru literele unice a doua cuvinte ... >>> a = set(abracadabra) >>> b = set(alacazam) >>> a # literele unice din a set([a, r, b, c, d]) >>> a - b # literele unice din b set([r, d, b]) >>> a | b # literele din a sau b set([a, c, r, d, b, m, z, l]) >>> a & b # literele atat din a cat si din b set([a, c]) >>> a ^ b # literele din a sau b , dar nu din amandoua set([r, d, b, m, z, l])

5.5

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 prin 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 de perechi cheie:valoare, ale c arei elemente sunt separate prin virgul a, : dic tionar = {jack:4098, Sape:4139}.Aceata este, de asemenea, o modalitate de a scrie dic tionare la dispozitivul de ie sire. 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:

5.5. Dic tionare

33

>>> 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.6

Tehnici de parcurgere a secven telor

Cnd se parcurge un dictionar, cheia si valoarea corespunz atoare se pot eviden tia simultan utiliznd metoda iteritems().
>>> knights = {gallahad: the pure, robin: the brave} >>> for k, v in knights.iteritems(): ... print k, v ... gallahad the pure robin the brave

, indexul pozi Cnd se parcurge o secven ta tiei s i valoarea corespunz atoare se pot g asi simultan utiliznd functia enumerate().
>>> for i, v in enumerate([tic, tac, toe]): ... print i, v ... 0 tic 1 tac 2 toe

Pentru a parcurge dou a sau mai multe secven te in acela si timp intr arile se pot mperechea cu functia zip().
>>> questions = [name, quest, favorite color] >>> answers = [lancelot, the holy grail, blue] >>> for q, a in zip(questions, answers): ... print What is your %s? It is %s. % (q, a) ... What is your name? It is lancelot. What is your quest? It is the holy grail. What is your favorite color? It is blue.

in ordine invers Pentru a parcurge o secven ta a, nti se specic a secven ta n ordine normal a, apoi se apeleaz a functia reversed().

34

Capitolul 5. Structuri de date

>>> for i in reversed(xrange(1,10,2)): ... print i ... 9 7 5 3 1

n ordine sortat Pentru a bucla o secven ta a, se folose ste func tia sorted(), care returneaz a o nou a list a sortat a, dar sursa r amne nealterat a.
>>> basket = [apple, orange, apple, pear, orange, banana] >>> for f in sorted(set(basket)): ... print f ... apple banana orange pear

5.7

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 ab 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 C este echivalent cu A and (not B) or C. Binen teles, pentru claritate, pute ti folosi paranteze pentru a combina condi tiile s i. 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.7. Mai multe despre condi tii

35

5.8

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: se compar a nti primul element din ecare list a. Dac a difer a este a sat rezultatul, 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 ini mai scurt dintre secven te 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)

Python permite s i 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 comparare ntre obiecte de tipuri diferite nu ar trebui considerate de foarte mare ncredere; acestea pot schimbate la versiuni viitoare ale limbajului.

36

Capitolul 5. Structuri de date

CAPITOLUL

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 aa 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 apoi 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 sirul lui Fibonacci pana la n a, b = 0, 1 while b < n: print b, a, b = b, a+b def fib2(n): # intoarce sirul 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:
>>> 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:

37

>>> 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. Instruc tiunile sunt menite s a realizeze ini tializarea modulului s i se execut a o singur a dat a, atunci cnd modulul este importat1 . 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. Este indicat ca instruc tiunile import pot plasate la nceputul programului s i, 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 (fibo nu este denit). Pentru a nc arca toate deni tiile modulului direct n tabela local a folosi ti sintaxa :
>>> from fibo import * >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377

Acum n tabela local a au fost nc arcate toate numele de variabile s i func tii din modul, mai putin cele care ncep cu caracterul _.

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 stare PYTHONPATH. Aceasta are aceea si sintaxa ca s i variabila de sistem PATH, care este o list a de directoare. Dac a variabila PYTHONPATH nu este denit a, sau modulul nu este gasit in directoarele din lista, atunci va c autat n directorul implicit de instalare, de obicei, in UNIX, /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.
1 De fapt declara tiile de func tii sunt tot instruc tiuni care sunt executate : execu tia inseamn a nc arcarea numelui func tiei n tabela de simboluri globale a modulului.

38

Capitolul 6. Module

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. Ori de cte ori 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 printr-un 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 -OO, compilatorul va genera cod optimizat, care n cazuri rare s a duc a la fuc tion ari eronate ale programului. n mod curent a se elimin a numai s irurile __doc__ din codul compilat, rezultnd siere .pyo mai compacte. 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 Un program nu func tioneaz a mai rapid, atunci cnd este citit dintr-un sier de tip .pyc sau .pyo, fa ta unul .py. Singurul lucru care difer a este viteza de nc arcare a programelor n memorie. Atunci cnd este rulat un script, prin lansarea interpretorului avnd ca parametru numele sierului n care se a a script-ul, 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 xxx.pyc (sau xxx.pyo dac a se folose ste O), f ar a ca sierul xxx.py asociat s a existe. Pute ti folosi aceast a facilitate atunci cnd distribui ti o bibliotec a ntr-un format de cod greu de decriptat. Modulul compileall poate folosit pentru a crea siere .pyc (sau .pyo, utiliznd -O) 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 n Python Library Reference. Unele module sunt integrate n interpretor, de si nu fac parte din nucleul limbajului, din deni tia acestuia, dar sau pentru a facilita accesul la primitivele sistemului de operare. Setul de module 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:
>>> import sys >>> sys.ps1 >>> >>> sys.ps2 ... >>> sys.ps1 = C> C> print Yuck! Yuck! C>

6.2. Module standard

39

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) [__displayhook__, __doc__, __excepthook__, __name__, __stderr__, __stdin__, __stdout__, _getframe, api_version, argv, builtin_module_names, byteorder, callstats, copyright, displayhook, exc_clear, exc_info, exc_type, excepthook, exec_prefix, executable, exit, getdefaultencoding, getdlopenflags, getrecursionlimit, getrefcount, hexversion, maxint, maxunicode, meta_path, modules, path, path_hooks, path_importer_cache, platform, prefix, ps1, ps2, setcheckinterval, setdlopenflags, setprofile, setrecursionlimit, settrace, stderr, stdin, stdout, version, version_info, warnoptions]

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 as 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

Capitolul 6. Module

>>> import __builtin__ >>> dir(__builtin__) [ArithmeticError, AssertionError, AttributeError, DeprecationWarning, EOFError, Ellipsis, EnvironmentError, Exception, False, FloatingPointError, FutureWarning, IOError, ImportError, IndentationError, IndexError, KeyError, KeyboardInterrupt, LookupError, MemoryError, NameError, None, NotImplemented, NotImplementedError, OSError, OverflowError, OverflowWarning, PendingDeprecationWarning, ReferenceError, RuntimeError, RuntimeWarning, StandardError, StopIteration, SyntaxError, SyntaxWarning, SystemError, SystemExit, TabError, True, TypeError, UnboundLocalError, UnicodeError, UserWarning, ValueError, Warning, ZeroDivisionError, _, __debug__, __doc__, __import__, __name__, abs, apply, basestring, bool, buffer, callable, chr, classmethod, cmp, coerce, compile, complex, copyright, credits, delattr, dict, dir, divmod, enumerate, eval, execfile, exit, file, filter, float, getattr, globals, hasattr, hash, help, hex, id, input, int, intern, isinstance, issubclass, iter, len, license, list, locals, long, map, max, min, object, oct, open, ord, pow, property, quit, range, raw_input, reduce, reload, repr, round, setattr, slice, staticmethod, str, sum, super, tuple, type, unichr, unicode, vars, xrange, zip]

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 crearea s i ntre tinerea unei colec tii de module n continu 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 ierarhii de siere):

6.4. Pachete

41

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 fisiere

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:
import Sound.Effects.echo

Instruc tiunea de mai sus a nc arcat submodulul Sound.Effects.echo. O func tie con tinut a de submodul 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

Aici se ncarc a, de asemenea, submodulul echo, dar fuctia echofilter() poate accesat direct :
echofilter(input, output, delay=0.7, atten=4)

42

Capitolul 6. Module

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:
__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 n spa tiul numeleor curent deoarec sunt denite n pachetul Sound.Effects cnd instruc tiunea from ...import este executat a ( acest lucru func tioneaz as i cnd se dene ste __all__). Nu este foarte ecient s a folosi ti instruc tiuni de tipul import *, pentru c a n acest fel codul dumneavoastr a va deveni ambiguu, 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, aceasta ind s i sintaxa recomandat a.

6.4.2

Referen tieri ntre pachete

Apare deseori necesitatea ca ntr-un submodul s a se foloseasc a cod dintr-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 6.4. Pachete 43

import examinaez a nti pachetul cel mai cuprinz ator, s i apoi caut a n lista de directoare. Cu toate acestea 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 module 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.3

Pachete n directoare multiple

Pachetele suporta un atribut special, __path__.Acest atribut este ini tializat ca o lista care con tine numele directorului n care se g ase ste __init.py__ul pachetului nainte de executarea codului din sier. Aceast a variabil a se poate modica, f acndu- si efectul pentru viitoarele c aut ari de module s i subpachete con tinute n pachet. Ct timp aceast a component a nu se utilizeaz a prea des, se poate folosi pentru extinderea setului de module g asite in pachet.

44

Capitolul 6. Module

CAPITOLUL

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 utilizator, 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 de ie Formatarea 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:
>>> s = Hello, world. >>> str(s) Hello, world. >>> repr(s) "Hello, world." >>> str(0.1) 0.1 >>> repr(0.1) 0.10000000000000001 >>> x = 10 * 3.25 >>> y = 200 * 200 >>> s = The value of x is + repr(x) + , and y is + repr(y) + ... >>> print s The value of x is 32.5, and y is 40000... >>> # The repr() of a string adds string quotes and backslashes: ... hello = hello, world\n >>> hellos = repr(hello) >>> print hellos hello, world\n >>> # The argument to repr() may be any Python object: ... repr((x, y, (spam, eggs))) "(32.5, 40000, (spam, eggs))" >>> # reverse quotes are convenient in interactive sessions: ... 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 a c arui dimensiune este dat a de utilizator, introducnd spa tii la stnga s irului. Exist as 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:


>>> 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 : 46 s Capitolul 7. Intrari i ie siri

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

Citirea s i scrierea sierelor

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 e doar 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. 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. Citirea s i scrierea sierelor

47

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, atunci din sier vor citi ti cel mult at tia octe ti 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 octe ti c ti sunt specica ti prin acest parametru s i nc a at tia octe ti 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 f.write(s ir) scrie con tinutul s irului de caractere n sier, ntorc and, ca rezultat, None:
>>> f.write(This is a test\n)

Dac a se dore ste scrierea a altceva dact s ir de caractere, atunci, mai ti, acesta trebuie convertit in s ir :
>>> value = (the answer, 42) >>> s = str(value) >>> f.write(s)

Metoda f.tell() are ca rezultat un num ar ntreg reprezentnd pozi tia cursorului n sier, pozi tie de nceputul m asurat a n octe ti fa ta sierului. Pentru a schimba pozi tia cursorului folosi ti metoda f.seek(deplasare,referin t a). Noua pozi tie este calculat a n felul urm ator: cursorul va deplasat de nceputul de pozi cu deplasare octe ti, fa ta sierului dac a referin t a este 0, fa ta tia curent a a cursorului 48 s Capitolul 7. Intrari i ie siri

este 2. Dac de sfr dac a referin t a este 1 s i fa ta situl sierului dac a referin ta a al doilea parametru este va nceputul omis, valoarea lui implicit a va 0, deci punctul de referin ta sierului:
>>> >>> >>> >>> 5 >>> >>> d f=open(/tmp/workfile, r+) f.write(0123456789abcdef) f.seek(5) # Salt la al 5-le byte din fisier f.read(1) f.seek(-3, 2) # Salt la al 3-lea byte de la sfarsitul fisierului 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. Un astfel de mecanism este complet inecient. Pentru aceste situa tii, s i altele mult mai complexe, 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. Citirea s i scrierea sierelor

49

50

CAPITOLUL

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, 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-o. 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 o 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:
>>> 10 * (1/0) Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: integer division or modulo by zero >>> 4 + spam*3 Traceback (most recent call last): File "<stdin>", line 1, in ? NameError: name spam is not defined >>> 2 + 2 Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: cannot concatenate str and int objects

Ultima linie a mesajului de eroare indic a ce s-a ntmplat. Excep tiile sunt de diferite tipuri, iar tipul excep tiei este

51

de asemenea a sat n corpul mesajului de eroare. n exemplul anterior: ZeroDivisionError, NameError s i TypeError, desemneaz a tipul excep tiei. Sirul a sat 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.Numele excep tiilor standard sunt identicatori predeni ti, nu cuvinte rezervate. A doua parte a liniei reprezint a detaliile excep tiei, descriind mai bine ce s-a ntmplat. tiile implicite s i semnica tiile lor. n Python Library Reference sunt listate excep

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 a o bucl a care cere utilizatorului introducerea unui num ar. Bucla este ntrerupt a n momentul n care utilizatorul introduce un num ar corect, altfel 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 rstul instruc tiunilor din acest bloc sunt s arite. Dac a tipul excep tiei este acela pe care l trateaz as i blocul except, atunci sunt executate instru tiunile din acest bloc. Dup a ce excep tia este tratat a, execu tia programului continu a cu instruc tiunile ce urmeaz a instruc tiunii try. Dac a excep tia generat a nu este prev azut a ntre excep tiile tratate n blocul except, ea este transmis a n afara blocului try.Dac a nu este g asit un bloc except care s a trateze excep tia, aceasta va o excep tie netratat a. Programul este ntrerupt, a snd mesajul : unhandled exception. 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. Clauza din exemplul urm ator poate trata mai multe tipuri de excep tii desemnate printr-o lista inchis a ntre paranteze :
... 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 ao 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:

52

Capitolul 8. Erori s i excep tii

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 in integer" 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 de preferat ad aug arii 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. Clauza except poate accepta o variabil a dup a numele excep tiei, sau o list a de nume de excep tii.Variabila este legata de instan ta excep tiei, cu argumentele salvate n instance.args. Prin conven tie instan ta excep tiei dene ste __getitem__ s i __str__ si argumentele pot accesate, sau listate, direct, f ara a mai referi .args.
>>> try: ... raise Exception(spam, ... except Exception, inst: ... print type(inst) # ... print inst.args # ... print inst # ... x, y = inst # ... print x =, x ... print y =, y ... <type instance> (spam, eggs) (spam, eggs) x = spam y = eggs eggs) instanta exceptiei argumentele stocate in .args __str__ permite args sa fie listate direct __getitem__ permite args sa fie despachetate direct

Dac a o excep tie are un argument, acesta va a sat n ultima parte ("detaliu") a mesajului de excep tie netratat a. ntr-un bloc try nu sunt tratate numai excep tiile generate imediat n cadrul blocului, ci s i dac a acestea apar n func tiilor apelate (chiar s i indirect) in bloc. De exemplu:

8.3. Tratarea excep tiilor

53

>>> 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 semnalat 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

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 derivate din clasa Exception att n mod direct ct s i indirect. De exemplu :

54

Capitolul 8. Erori s i excep tii

>>> 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 :
class Error(Exception): """Base class for exceptions in this module.""" pass class InputError(Error): """Excetie generata pentru eroare de intrare. Atribute: expression -- expresia de intrare in care apare eroarea message -- explicarea erorii """ def __init__(self, expression, message): self.expression = expression self.message = message class TransitionError(Error): """Generata cand o operatie asteapta o modificare de stare care nu este permisa Attributes: previous -- starea la inceputul tranzitiei next -- noua stare care este de asteptat sa apara message -- explicatie privind imposibilitatea tranzitiei """ 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 n func tiile denite de ele. Mai multe informa tii despre clase ve ti g asi n capitolul dedicat acestora.

8.5. Excep tii denite de utilizator

55

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 . De exemplu: orice 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, aceasta este regenerat a dup a ce sunt executate instruc tiunile clauzei finally. Clauza finally este de asemenea executat a la ie sire, chiar s i atunci cnd a fost apelat a o instruc tiune break sau return. Codul scris n clauza finally este util 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.

56

Capitolul 8. Erori s i excep tii

CAPITOLUL

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 a o 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 : mecanismul de mo stenire permite clase de baz a multiple, o clas a derivat a poate suprascrie orice metod a a clasei/claselor de baz a, o metod a poate poate apela o metod a a clasei de baz a cu acela si nume. Obiectele au un num ar arbitrar de date private. n terminologie C++, toate componentele unei clase (inclusiv 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 unui obiect din cadrul unei metode a acelui obiect: metodele sunt declarate cu un prim argument explicit reprezentnd obiectul, care este apoi transmis automat n momentul apelarii. Ca s i n Smalltalk clasele ins ale sunt n sine obiecte ; n sens mai larg: n Python toate tipurile de date sunt obiecte. Astfel sunt posibile importurile s i redenumirile. Spre deosebire de C++ s i Modula-3, tipurile predenite pot utilizate drept clase de baz a de c atre utilizator. 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 instan tierile claselor.

9.1

Cteva cuvinte despre terminologie

Deoarece nu exist a o terminologie unanim recunoscut a n ceea ce prive ste clasele, 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, deci 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 capcane de terminologie : cuvntul : n Python cuv antul obiect nu nseamn a obligatoriu o instan tiere a unei clase. Ca s i n C++ s i Modula-3, dar nu s i ca n SmallTalk, n Python unele tipuri de date nu sunt neap arat clase: numerele ntregi s i listele, dar s i alte tipuri de date mai exotice, ca sierele nu sunt clase. Toate tipurile de date din Python au, semantic, ceva comun, care este mai u sor de explicat dac a ne referim la ele 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, n alte limbaje, aliasing. 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 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, apelantul va putea observa modic arile f acute asupra obiectului s i nu asupra reprezent arii locale. Acestea elimina necesitatea folosirii a dou a mecanisme de transmitere a parametrilor, ca n Pascal.

57

9.2

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 Un domeniu de deni tii a numelor este o hart a de leg aturi ntre nume s i obiecte. n momentul de fa ta domenii 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 anume 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 crea 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 numele 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 se poate 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 este o regiune a unui program Python n care un anumit domeniu de deni tie a numelor la un nume va genera o c este accesibil. Accesibil nseamn a c a o anumit a referin ta autare n domeniul de deni tie al acelui modul, despre 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 s i ultimul n care se caut a un nume, dac a n celelalte c autarea nu a avut succes. Cel de al treilea nivel 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 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 este aceea c a atribuirile au loc n primul domeniu de vizibilitate(cel mai de

58

Capitolul 9. Clase

jos sau cel mai adnc)1 . 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 tiinile 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 clas a 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

Sintaxa de denire a 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 de ce cunoa pot uneori foarte utile. Deni tiile de func tii din cadrul unei clase sunt un pic deosebite fa ta ste ti pn a acum, 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 obiectele 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

(class) Obiecte clasa

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:
class MyClass: "Un exemplu simplu de clasa" i = 12345 def f(self): return hello world

N.T. termenul original este innermost

privire asupra claselor 9.3. O prima

59

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 valoarea : 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 creaz 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 clasa 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__(), la instan tierea ei se apeleaz a automat metoda __init_ ini _(). n acest fel se ob tine o instan ta tializat a a clasei :
x = MyClass()

Metoda __init__() poate avea s i 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 tiuni acceptate sunt opera tiunile cu atribute. Exist a dou a tipuri de nume de atribute valide : propriet a ti s i metode. Prima categorie sunt 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:
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 numai instan tei unei clase, adic a unui obiect clas a; s i alte tipuri 60 Capitolul 9. Clase

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 ntre MyClass.f s x.i nu este o metod a, pentru c a MyClass.i nu este o func tie. Exist a o diferen ta i x.f: MyClass.f este un obiect func tie iar x.f este 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 a sa 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, din corpul clasei, 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 este apelat a f ar a el, de si s-ar putea nici s a nu e utilizat. 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, care nu este un atribut dat a, al unei instan te este c autat n clasa din care face parte. Dac a numele reprezint a un atribut existent n respectiva clas a (un obiect de tip func tie), este s creat un obiect metod a mpachetnd obiectul instan ta i obiectul func tie(tocmai g asit). n acest fel se creeaza un obiect metod a. Atunci cnd un obiect metod a este apelat cu o list a de argumente, el este despachetat din nou, s o nou a list a de argumente este construit a din obiectul instan ta i lista de argumente original a. n cele din urm a obiectul func tie este apelat cu noua list a de argumente.

9.4

Alte observa tii

Atributele de tip dat a suprascriu atributele metod a cu acela si nume. Pentru a evita conicte de nume, ce pot cauza erori greu de g asit n programe mari, este bine s a folosi ti o conven tie pentru denumiri. 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. Atributele dat a pot accesate de metode la fel de bine ca 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 9.4. Alte observa tii 61

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:
# Functie definita inafara 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)

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 modulului 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 pe 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:

62

Capitolul 9. Clase

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 direct o metod a a clasei de baz a : 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:
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.5. Mo stenirea

63

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 _clas a__spam, unde suprimate. Mutilarea este realizat clas a este 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 cum 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

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 creaza o inregistrare vida 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 64 Capitolul 9. Clase

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.8

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

9.9

Iteratori

Pna acum a ti observat c a majoritatea obiectelor container se pot baleia utiliznd instruc tiunea for :

9.8. Excep tiile pot clase

65

for element in [1, 2, 3]: print element for element in (1, 2, 3): print element for key in {one:1, two:2}: print key for char in "123": print char for line in open("myfile.txt"): print line

Acest mod de accesare este clar,concis s i comod. Folosirea iteratorilor este larg raspndit a n proiectarea Pythonului. Prin modul s au de implementare instructiunea for apeleaz a iter() pentru obiectul container. Func tia returneaz a un obiect iterator care dene ste metoda next() prin care se acceseaz a doar o singur a dat a ecare element al containerului. Cnd toate elementele au fost epuizate, next() seteaz a excep tia StopIteration, care comunic a buclei for s a se opreasc a. Modul de func tionare este ilustrat de urm atorul exemplu :
>>> s = abc >>> it = iter(s) >>> it <iterator object at 0x00A1DB50> >>> it.next() a >>> it.next() b >>> it.next() c >>> it.next() Traceback (most recent call last): File "<pyshell#6>", line 1, in -toplevelit.next() StopIteration

Sa v azut mecanismul din spatele procesului de iterare.Este u sor de a implementa un comportament iterarativ claselor proiectate de c atre utilizator. Se dene ste o metod a __iter__(). Aceast a metod a returneaz a un obiect ce va avea o metod a next(). Dac a clasa dene ste next(), atunci __iter__() va returna doar self :
class Reverse: "Iterator for looping over a sequence backwards" def __init__(self, data): self.data = data self.index = len(data) def __iter__(self): return self def next(self): if self.index == 0: raise StopIteration self.index = self.index - 1 return self.data[self.index] >>> for char in Reverse(spam): ... print char ... m a p s

66

Capitolul 9. Clase

9.10

Generatori

Generatorii sunt instrumente simple s i puternice pentru crearea iteratorilor. Generatorii se scriu ca s i functiile obi snuite, dar se utilizeaz a instruc tiunea yield cnd se dore ste o returnare de date. De ecare dat a se apeleaz a next(), generatorul relund din locul de ntrerupere ( el memoreaz a toate valorile datelor s i ce instruc tiune a fost executat a ultima). Exemplul urm ator prezint a ct de simplu se poate crea un generator :
def reverse(data): for index in range(len(data)-1, -1, -1): yield data[index] >>> for char in reverse(golf): ... print char ... f l o g

Tot ce se poate face cu generatori se poate face s i cu clase bazate pe iteratori, descrise n sec tiunea anterioar a.Ce face ca generatorul s a e mai compact este faptul c a metodele __iter()__ s i next() sunt create automat. O alt a caracteristic a important a este aceea c a ntre apeluri sunt salvate variabilele locale s i starea execu tiei.Acest lucru face func tia mai u sor de scris si mai clar a dect abordarea cu variabile de clas a precum self.index s i self.data. n plus, la salvarea automat a a variabilelor s i a st arii programului, cnd generatorul si ncheie lucrul, seteaz a automat StopIteration.Toate aceste caracteristici dau posibilitatea de a scrie iteratori la fel de u sor ca s i o func tie obi snuit a.

9.11

Expresii generator

Unii generatori simpli se pot scrie succint ca expresii folosind o sintax a similar a cu cea a cre arii listelor obi snuite, dar cu paranteze n locul acoladelor.Aceste expresii sunt create pentru situa tiile in care generatorii sunt ceru ti ca atare n corpul unei unei func tii.Expresiile generator sunt mult mai compacte, dar s i mult mai pu tin cuprinz atoare dect denirea complet a a generatorilor s i tind s a e mai u sor de memorat dect datele de tip list a. De exemplu :
>>> sum(i*i for i in range(10)) # suma de patrate 285 >>> xvec = [10, 20, 30] >>> yvec = [7, 5, 3] >>> sum(x*y for x,y in zip(xvec, yvec)) 260 >>> from math import pi, sin >>> sine_table = dict((x, sin(x*pi/180)) for x in range(0, 91)) >>> unique_words = set(word for line in page for word in line.split()) >>> valedictorian = max((student.gpa, student.name) for student in graduates) >>> data = golf >>> list(data[i] for i in range(len(data)-1,-1,-1)) [f, l, o, g]

9.10. Generatori

67

68

CAPITOLUL

ZECE

Pe scurt despre Standard Library partea I


10.1 Interfa ta cu sistemul de operare

Modulul os con tine o serie de func tii pentru interfa tarea cu sistemul de operare :
>>> import os >>> os.system(time 0:02) 0 >>> os.getcwd() # Returneaza directorul de lucru curent C:\\Python24 >>> os.chdir(/server/accesslogs)

Asigura tiv a c a folosi ti import os n loc de from os import *. Aceasta va mpiedica os.open() s a estompeze efectul func tiei predenite open(), care lucreaza ntr-un mod mult diferit. Fuc tiile predenite dir() s i help() sunt foarte utile ca un ajutor interactiv pentru lucrul cu module de dimensiuni mari, cum este cazul modulului os :
>>> import os >>> dir(os) <returns a list of all module functions> >>> help(os) <returns an extensive manual page created from the modules docstrings>

de nivel Pentru administrarea sierelor curente s i a directoarelor de lucru,modulul shutil furnizeaz a o interfa ta nalt, u sor de folosit :
>>> import shutil >>> shutil.copyfile(data.db, archive.db) >>> shutil.move(/build/executables, installdir)

10.2

Fi sierele Wildcard (asterisc)

Modulul glob ofer a o func tie pentru realizarea listei cu sierele c autate ntrun director folosind asterisc n locul numelui :

69

>>> import glob >>> glob.glob(*.py) [primes.py, random.py, quote.py]

10.3

Argumentele n linia de comanda

Scripturil obi snuite reclam a adesea procesarea liniilor de comand a cu argumente. Aceste argumente sunt depozitate, sub form a de list a, n atributele argv al modulului sys. Spre exemplu, n urma execu tiei urm atoarei linii de comand a Python demo.py one two three va rezulta :
>>> import sys >>> print sys.argv [demo.py, one, two, three]

Modulul getopt prelucreaz a sys.argv aplicd regula functiei UNIX getopt(). O prelucrare mai puternic as i mai exibil a a liniei de comand a este oferit a de modulul optparse.

10.4

erorilor s Redirectarea semnalarii i terminarea execu tiei programului

Modulul sys con tine s i atribute pentru stdin, stdout s i stderr. Cel din urm a este utilizat pentru generarea de avertismente s i mesaje de eroare, pentru a le face vizibile chiar s i cnd stdout este redirectat :
>>> sys.stderr.write(Warning, log file not found starting a new one\n) Warning, log file not found starting a new one

Modalitatea cea mai direct a de a ncheia un scrip este aceea de a folosi sys.exit().

10.5

s Unicarea tratarii irurilor

Modulul re ofer a ca instrumente expresii standard pentru procesarea de nivel avansat a s irurilor. Pentru potriviri complexe si pentru lucrul cu s irurile, sunt puse la dispozi tia utilizatorului expresii care ofer a solu tii optimizate s i rapide :
>>> import re >>> re.findall(r\bf[a-z]*, which foot or hand fell fastest) [foot, fell, fastest] >>> re.sub(r(\b[a-z]+) \1, r\1, cat in the the hat) cat in the hat

Cnd impuse doar capabilit a ti reduse, atunci este de preferat lucrul cu metodele specice s irurilor, pentru c a sunt u sor de citit s i de depanat :
>>> tea for too.replace(too, two) tea for two

70

Capitolul 10. Pe scurt despre Standard Library - partea I

10.6

Module matematice

Modulul math ofer a acces la func tiile din structura bibliotecii C pentru calculul n virgul a mobil a:
>>> import math >>> math.cos(math.pi / 4.0) 0.70710678118654757 >>> math.log(1024, 2) 10.0

Modulul random are unelte pentru a face selec tii aleatorii :


>>> import random >>> random.choice([apple, pear, banana]) apple >>> random.sample(xrange(100), 10) # exemplificare fara inlocuire [30, 83, 16, 4, 8, 81, 41, 50, 18, 33] >>> random.random() # flotant obtinut aleatoriu 0.17970987693706186 >>> random.randrange(6) # intreg aleatoriu obtinut cu range(6) 4

10.7

Accesul la Internet

Sunt o mul time de module pentru accesarea internetului s i pentru procesarea protocoalelor de Internet. Dou a dintre cele mai simple sunt urllib2, pentru ob tinerea datelor de la url-uri, s i smtplib, pentru trimiterea mesajelor prin po st a electronic a:
>>> import urllib2 >>> for line in urllib2.urlopen(http://tycho.usno.navy.mil/cgi-bin/timer.pl): ... if EST in line: # look for Eastern Standard Time ... print line <BR>Nov. 25, 09:43:32 PM EST >>> import smtplib >>> server = smtplib.SMTP(localhost) >>> server.sendmail(soothsayer@example.org, jcaesar@example.org, """To: jcaesar@example.org From: soothsayer@example.org Beware the Ides of March. """) >>> server.quit()

10.8

Data s i timpul

Modulul datetime furnizeaz a clase pentru prelucrarea datei s i a timpului att ntr-o manier a simplist a, ct s i intruna mai elaborat a. Modulul implementeaz a si aritmetica datei s i a timpului. O aten tie deosebit a se acord a acces arii eciente a membrilor, pentru formatarea lor la a sare s i pentru prelucrare. De asemenea sunt implementate s i obiecte care sunt legate de ora local a.

10.6. Module matematice

71

# datele sunt usor de construit si formatat >>> from datetime import date >>> now = date.today() >>> now datetime.date(2003, 12, 2) >>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.") 12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December. # datele suporta artmetica de tip calendar >>> birthday = date(1964, 7, 31) >>> age = now - birthday >>> age.days 14368

10.9

Compresarea datelor

Formatele de arhiv are s i compresare obi snuite sunt accesate direct prin includerea modululelor zlib, gzip, bz2, zipfile s i tarfile.
>>> import zlib >>> s = witch which has which witches wrist watch >>> len(s) 41 >>> t = zlib.compress(s) >>> len(t) 37 >>> zlib.decompress(t) witch which has which witches wrist watch >>> zlib.crc32(t) -1438085031

10.10

Masurarea performan tei

ntre diferite abord Unii utilizatoru Python sunt interesa ti de cunoa sterea diferen telor de performan ta ari ale aceleia si probleme.Python ofera instrumente de m asur a, care r aspunde rapid cererilor. Exista tenta tia foloseriii impachet arii s i a despachet arii perechilor (tuple) in locul obi snuitei schimb ari intre argu: mentelor. Modulul timeit eviden tiaz a imediat un mic avantaj de performan ta
>>> from timeit import Timer >>> Timer(t=a; a=b; b=t, a=1; b=2).timeit() 0.57535828626024577 >>> Timer(a,b = b,a, a=1; b=2).timeit() 0.54962537085770791

n contrast cu timeit, care opereaz a pe coduri de foarte mici dimensiuni, modulele profile si pstats au instrumente pentru identicarea sec tinii de timp critic pentru aplicatii de mari dimensiuni.

72

Capitolul 10. Pe scurt despre Standard Library - partea I

10.11

tii programului Controlul calita

este aceea cnd pentru ecare func O abordare a program arii de performan ta tie se sciu, n faza de proiectare, teste ce vor rulate pe perioada ntregului proces de dezvoltare a aplica tiei. Modulul doctest ofera un instrument de scanare a unui modul si de vericare a bunei func tion ari a testului implantat in docstring-ul programului. Implantarea testului n docstring este u soar a.n docstring se va inscrie o apelare a func tie mpreun a cu rezultatul execu tiei. Aceast a implementare ofer a utilizatorului un exemplu de utilizare a func tiei si permite modulului doctest s a se verice conformitatea codului cu descrierea din documenta tie :

def average(values): """Computes the arithmetic mean of a list of numbers. >>> print average([20, 30, 70]) 40.0 """ return sum(values, 0.0) / len(values) import doctest doctest.testmod()

# verificarea automata a testului din documentatia functiei

Cu modulul unittest nu se lucreaz a mai u sor dect cu modulul doctest, dar el ofer a posibilitatea scierii unui program intrun sier cu un set complet de teste.
import unittest class TestStatisticalFunctions(unittest.TestCase): def test_average(self): self.assertEqual(average([20, 30, 70]), 40.0) self.assertEqual(round(average([1, 5, 7]), 1), 4.3) self.assertRaises(ZeroDivisionError, average, []) self.assertRaises(TypeError, average, 20, 30, 70) unittest.main() # Calling from the command line invokes all tests

10.12

Python oferit "la cheie"

Limbajul Python este un limbaj oferit "la cheie", lucru dovedit de complexitatea s i robuste tea ntregii distribu tii. De exemplu : Modulele xmlrpclib s i SimpleXMLRPCServer fac implement ari de proceduri apelabile de la distan ta de c atre aproape orice aplica tie. n ciuda numelui nu este necesar a cunoa sterea sau utilizarea XML. Pachetul email este o bibliotec a pentru prelucrarea mesajelor de email, incluznd s i mesajele tipice MIM s i RFC 2822. Spre deosebire de smptlib s i poplib, care, de fapt, transmit s i recep tioneaz a mesajele, pachetul email ofer a un set complet de instrumente necesare la constituirea s i decodarea structurilor comlexe ale mesajelor (inclusiv ata sare de siere - attachments) s i pentru implementarea protocoalelor de codare Internet s i a headerelor. Pachetele xml.dom s i xml.sax ofera un suport puternic pentru analizarea unui text scris XML, un format foarte r aspndit. n acela si fel modulul csv suport a scrierea s i citirea ntr-un format de baz a de date comun. mpreuna aceste module s i pachete simplic a ntr-un mod elegant schimbarea de date ntre aplica tiile Python si alte instrumente. tii programului 10.11. Controlul calita 73

Interna tionalizarea este asigurat a de un num ar de module ce inglobeaz a pachetele gettext, locale s i codecs.

74

Capitolul 10. Pe scurt despre Standard Library - partea I

CAPITOLUL

UNSPREZECE

Pe scurt despre Standard Library partea II


n partea a doua a scurtei prezent ari a Standard Library sunt analizate modulele necesare unei program ari profesionale. Aceste module apar arareori in scripturile mici.

11.1

Formatarea datelor de ie sire

Modulul repr furnizeaz a o versiune a func tiei repr() pentru a sarea prescurtat a a unor containere de lungime mare :
>>> import repr >>> repr.repr(set(supercalifragilisticexpialidocious)) "set([a, c, d, e, f, g, ...])"

Modulul pprint execut a un control mai sosticat, att asupra list arii obiectelor predenite, ct s i a celor denite de utilizator, ntr-un mod care poate usor citit de utilizator. Cnd reprezentarea este mai lunga dect o linie, "pretty printer" for teaz a sfr situl liniei s i face alinierea, pentru o mai mare claritate n a sarea structurii de date :
>>> import pprint >>> t = [[[[black, cyan], white, [green, red]], [[magenta, ... yello],blue]]] ... >>> pprint.pprint(t, width=30) [[[[black, cyan] white [green, red]], [[magenta, yellow], blue]]]

Modulul textwrap formateaz a paragrafele textului pentru a se putea ncadra ntr-o anumit a dimensiune impus a de programator pentru fereastra de a sare a datelor :

75

>>> import textwrap >>> doc = """The wrap() method is just like fill() except that it returns ... a list of strings instead of one big string with newlines to separate ... the wrapped lines.""" ... >>> print textwrap.fill(doc, width=40) The wrap() method is just like fill() except that it returns a list of strings instead of one big string with newlines to separate the wrapped lines.

Modulul locale acceseaz a o baz a de date cu formate de reprezentare specice diferitelor zone culturale ale lumii.Prin gruparea formatelor specice zonelor se pot a sa numerele avnd caractere specice de separare a cifrelor, precum s i semnului monetar specic :
>>> import locale >>> locale.setlocale(locale.LC_ALL, English_United States.1252) English_United States.1252 >>> conv = locale.localeconv() # se incarca parametrii zonali >>> x = 1234567.8 >>> locale.format("%d", x, grouping=True) 1,234,567 >>> locale.format("%s%.*f", (conv[currency_symbol], ... conv[int_frac_digits], x), grouping=True) $1,234,567.80

11.2

Sirurile s ablon (Templating)

Modulul string con tine o clas a Template exibil a,cu o sintax a simplicat a, util a n editare.Aceasta permite utilizatorului s a- si personalizeze aplica tiile. Formatul folose ste cuvinte s ablon alc atuite dintr-un delimitator (caracterul $) urmat de un identicator recunoscut de Python ( sir de caractere alfanumerice s i underscore). ncadrnd s ablonul ntre acolade se permite continuarea acestuia cu un s ir de caractere alfanumerice, care s a nu e separate prin spa tii. Caracterul $ se reprezint a scriind $$ :
>>> from string import Template >>> t = Template(${village}folk send $$10 to $cause.) >>> t.substitute(village=Nottingham, cause=the ditch fund) Nottinghamfolk send $10 to the ditch fund.

Metoda substitute seteaz a KeyError cnd un s ablon nu este g asit ntr-un dic tionar, sau ntr-un argument de tip cuvnt cheie. Pentru aplica tiile de tip email utilizatorul poate omite completarea unor date. De aceea se recomand a utilizare metodei safe_substitute, ea lasnd nemodicat s ablonul cu data curespunz atoare lips a:
>>> t = Template(Return the $item to $owner.) >>> d = dict(item=unladen swallow) >>> t.substitute(d) Traceback (most recent call last): . . . KeyError: owner >>> t.safe_substitute(d) Return the unladen swallow to $owner.

76

Capitolul 11. Pe scurt despre Standard Library - partea II

Pentru s irurile s ablon utilizatorul poate alege un anumit delimitator.De exemplu se poate alege drept delimitator caracterul % :
>>> import time, os.path >>> photofiles = [img_1074.jpg, img_1076.jpg, img_1077.jpg] >>> class BatchRename(Template): ... delimiter = % >>> fmt = raw_input(Enter rename style (%d-date %n-seqnum %f-format): Enter rename style (%d-date %n-seqnum %f-format): Ashley_%n%f >>> t = BatchRename(fmt) >>> date = time.strftime(%d%b%y) >>> for i, filename in enumerate(photofiles): ... base, ext = os.path.splitext(filename) ... newname = t.substitute(d=date, n=i, f=ext) ... print %s --> %s % (filename, newname) img_1074.jpg --> Ashley_0.jpg img_1076.jpg --> Ashley_1.jpg img_1077.jpg --> Ashley_2.jpg

O alt a aplicabilitate a s irurilor s ablon se g ase ste n prelucrarea datelor de ie sire scrise n diferite formate. Aceasta se realiz a nlocuind s abloanele denite de utilizator pentru sierele XML, rapoartele text, sau rapoartele web scrise n HTML.

11.3

binare ale datelor Lucrul cu reprezentari

Modulul struct are func tiile pack() s i unpack() pentru lucrul cu formate de nregistrare binar a a datelor cu lungime variabil a. Exemplul urm ator prezint a cum se pot c auta informa tii prin header-ul unui sier ZIP (cu cod de mpachetare "H" s i "L", reprezentnd numere f ara semn de doi, respectiv, patru octe ti) :
import struct data = open(myfile.zip, rb).read() start = 0 for i in range(3): # prezinta primele 3 headere ale fisierului start += 14 fields = struct.unpack(LLLHH, data[start:start+16]) crc32, comp_size, uncomp_size, filenamesize, extra_size = fields start += 16 filename = data[start:start+filenamesize] start += filenamesize extra = data[start:start+extra_size] print filename, hex(crc32), comp_size, uncomp_size start += extra_size + comp_size # sare la urmatorul header

11.4

Multi-threading

Threading este o tehnic a prin care se realizeaz a decuplarea procesele care nu sunt dependente secven tial unul de cel alalt. Aceast a tehnic a se poate folosi pentru mbun at a tirea r aspunsului aplica tiilor care primesc date de la utilizator, atunci cnd alte procese ruleaz a n background. Un astfel de caz este acela n care un proces de intrare/ie sire ruleaz a n paralel cu un proces de calcul. Urm atorul program prezint a cum modulul de nivel nalt threading poate executa procese in background, n timp ce programul principal continu a s a ruleze :

binare ale datelor 11.3. Lucrul cu reprezentari

77

import threading, zipfile class AsyncZip(threading.Thread): def __init__(self, infile, outfile): threading.Thread.__init__(self) self.infile = infile self.outfile = outfile def run(self): f = zipfile.ZipFile(self.outfile, w, zipfile.ZIP_DEFLATED) f.write(self.infile) f.close() print Finished background zip of: , self.infile background = AsyncZip(mydata.txt, myarchive.zip) background.start() print The main program continues to run in foreground. background.join() # Wait for the background task to finish print Main program waited until background was done.

Principala provocare in proiectarea aplica tiilor multi-threading este aceea de a coordona thread-urile care partajeaz a acelea si date, sau acelea si resurse. La sr sit, modulele thread genereaz a un num ar de primitive de sincronizare precum : variabile de blocare, de stare, indicatori de tip semafor.

11.5

Conectivitatea (Logging)

Modulul logging ofer a un sistem de conectare exibil s i cu toate caracteristicile specice unui astfel de sistem.Mesajele de conectare sunt transmise c atre un sier, sau c atre sys.stderr :
import logging logging.debug(Debugging information) logging.info(Informational message) logging.warning(Warning:config file %s not found, server.conf) logging.error(Error occurred) logging.critical(Critical error -- shutting down)

Acestea transmit urm atoarele :


WARNING:root:Warning:config file server.conf not found ERROR:root:Error occurred CRITICAL:root:Critical error -- shutting down

Implicit mesajele cu informa tii si cele de depanare sunt suprimate s i ie sirea este direc tionat a c atre stderr. Alte op tiuni de ie sire includ rutarea mesajelor prin email, datagrame, soket, sau server HTML. Folosind ltre noi se pot selecta diferite rute func tie de prioritatea mesajului : DEBUG, INFO, WARNING,ERROR, CRITICAL. Sistemul de conectare (loggin) poate congurat direct de Python, dar poate s i preluat dintr-un sier de congurare editat de utilizator, pentru a particulariza conectarea f ar a a altera setarea mediului.

78

Capitolul 11. Pe scurt despre Standard Library - partea II

11.6

Legaturi slabe la memorie

Pentru ecare obiect, Python realizeaz a o leg atura a acestuia cu memorie.Leg atura poate puternic a (permanent a), sau slab a (de scurt a durat a). Aceste leg aturi sunt administrate n mod automat, prin contorizarea leg aturilor obiectelor s i prin folosirea "co sului de gunoi" pentru eliminarea ciclurilor.Memoria este eliberat a imediat ce ultima referire la ea a fost eliminat a. Acest comportament func tioneaz a bine pentru majoritatea aplica tiilor, dar uneori se dore ste s a se urm areasc a obiectele doar att timp ct sunt utilizate de alt a aplica tie.Din p acate aceast a urm arire produce o leg atur a permanent a la memorie.Modulul weackref ofer a instrumente pentru urm arirea obiectelor prin crearea unor leg aturi slabe. Cnd un biect nu mai este necesar va automat eliminat din tabela de leg aturi slabe.
>>> import weakref, gc >>> class A: ... def __init__(self, value): ... self.value = value ... def __repr__(self): ... return str(self.value) ... >>> a = A(10) # creaza o legatura >>> d = weakref.WeakValueDictionary() >>> d[primary] = a # nu creaza legatura >>> d[primary] # fetch the object if it is still alive 10 >>> del a # elimina o referinta >>> gc.collect() # activeaza "cosul de gunoi" 0 >>> d[primary] # intrarea a fost eliminata automat Traceback (most recent call last): File "<pyshell#108>", line 1, in -topleveld[primary] # entry was automatically removed File "C:/PY24/lib/weakref.py", line 46, in __getitem__ o = self.data[key]() KeyError: primary

11.7

Instrumente de lucru cu listele

Multe structuri de date se contruiesc cu ajutorul listelor predenite.Oricum, uneori se impune necesitatea unei implement ari alternative cu performan te diferite de cele obi snuite. Modulul array ofer a obiectul array() care se comporta ca o list a care cuprinde numai obiecte de acela si fel, dar care sunt stocate mai compact dect n cazul listei standard.n urm atorul exemplu se prezint a cum un array1 de numere memorate ca numere binare f ara semn reprezentate pe doi octe ti (cod de tip "H") este contrapus utiliz arii unei liste standard de obiecte Python de tip int, reprezentate pe 16 octe ti :
>>> from array import array >>> a = array(H, [4000, 10, 700, 22222]) >>> sum(a) 26932 >>> a[1:3] array(H, [10, 700])

Modulul collection con tine obiectul deque() care se aseam ana a cu tipul list a, cu ad aug ari si scoateri rapide de elemente prin stnga, dar cu o accesarea lent a a mijlocului.Aceste obiecte sunt convenabile pentru implementarea cozilor s i a caut arii pe nivel pentru arbori :
1

Array = Lista cu valori de acela si tip care se pot referi individual

11.6. Legaturi slabe la memorie

79

>>> from collections import deque >>> d = deque(["task1", "task2", "task3"]) >>> d.append("task4") >>> print "Handling", d.popleft() Handling task1

unsearched = deque([starting_node]) def breadth_first_search(unsearched): node = unsearched.popleft() for m in gen_moves(node): if is_goal(m): return m unsearched.append(m)

Biblioteca ofer a, tot pentru alternativa la implementarea cu liste, s i modulul bisect cu func tii pentru manipularea listelor sortate :
>>> import bisect >>> scores = [(100, perl), (200, tcl), (400, lua), (500, python)] >>> bisect.insort(scores, (300, ruby)) >>> scores [(100, perl), (200, tcl), (300, ruby), (400, lua), (500, python)]

Modulul heapq con tine func tii pentru implementarea de heap 2 utiliznd listele standard.Valoarea intr arii celei mai mici este tinut a permanent la pozi tia zero. Acest lucru este util pentru aplica tiile n care se acceseaz a repetitiv elementul cel mai mic, dar nu se dore ste o sortare complet a a listei:
>>> from heapq import heapify, heappop, heappush >>> data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0] >>> heapify(data) # rearanjeaza lista in ordinea heap >>> heappush(data, -5) # se adauga o noua intrare >>> [heappop(data) for i in range(3)] # aduce cele mai mici trei intrari [-5, 0, 1]

11.8

otanta zecimala Aritmetica n virgula

Modulul decimal ofer a, pentru aritmetica n virgul a otant a, tipul de data Decimal.Comparndo cu clasa predenit a float, implementat a pentru lucrul n virgul a otant a binar a, noua clas a este necesar a n aplica tiile nanciare s i, n general, n aplica tiile care necesit a : o reprezentare zecimal a exact a, o precizie ridicat a, o rotunjire impus a foarte bun a, pozi tionarea zecimalelor semnicative. O alt a ntrebuin tare ar pentru aplica tiile n care utilizatorul dore ste confruntarea calculelor cu cele executate manual. De exemplu, calculnd taxa de 5% pentru o convorbire telefonic a de 70 de cen ti, folosind aritmetica n virgul a otant a zecimal s i cea binar a se ob tin rezultate diferite :
2 Heap = por tiune de memorie rezervat a pentru a utilizat a de un program ca zon a de stocare temporar a a unor structuri de date a c aror nu se pot determina dect n timpul rul m arime, sau existen ta arii programilui.

80

Capitolul 11. Pe scurt despre Standard Library - partea II

>>> from decimal import * >>> Decimal(0.70) * Decimal(1.05) Decimal("0.7350") >>> .70 * 1.05 0.73499999999999999

n exemplu, rezultatul func tiei Decimal men tine la sf ar sit un zero pentru ca partea zecimal a s a e compus a din patru cifre. Astfel se simuleaz a calculul f acut cu mna, cnd nmultind doua numere, ecare cu dou a zecimale se ob tine la rezultat partea zecimal a din patru cifre.n acest fel se evit a situa tia care apare cnd aritmetica n virgul a otant a binar a nu reprezint a precis cantitatea zecimal a. Pentru c a returneaz a rezultatul exact clasa Decimal este folosit a n calcule modulo s i n teste de egalitate, domenii pentru care aritmetica n virgul a otant a binar a nu este aplicabil a:
>>> Decimal(1.00) % Decimal(.10) Decimal("0.00") >>> 1.00 % 0.10 0.09999999999999995 >>> sum([Decimal(0.1)]*10) == Decimal(1.0) True >>> sum([0.1]*10) == 1.0 False

Modulul Decimal poate executa calcule cu o precizie impus a de utilizator :


>>> getcontext().prec = 36 >>> Decimal(1) / Decimal(7) Decimal("0.142857142857142857142857142857142857")

otanta zecimala 11.8. Aritmetica n virgula

81

82

CAPITOLUL

DOISPREZECE

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? a foarte detaliat ecare Ar trebui s a citi ti, sau cel pu tin s a r asfoi ti Python Library Reference,document ce explic 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. a documenta tii buc a ti de cod scrise de al ti proUn site foarte util este http://www.python.org. Aici exist gramatori 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 Python-list@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 aspunsurile de la aceast a adres a, la poate g asit a la adresa http://www.python.org/doc/faq.html. R diferite ntreb ari puse de al ti programatori, v a pot ajuta de foarte multe ori n rezolvarea problemelor dumneavoastr a.

83

84

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. C-P revine la o comand a anterioar a n buffer celei executate. C-M nainteaz a la urm atoarea instruc tiune din buffer. 85

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. 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.
1 Python va executa con tinutul unui sier identicat prin variabila de mediu PYTHONSTARTUP n momentul pornirii interpretorului interactiv.

86

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

# # # # # # # # # #

La interpretorul interactiv Python se adauga functia de autocompletare si un fisier de tip jurnal pentru comenzi. Se cere Python 2.0+, readline. Autocompletarea este executata implicit prin tasta Esc (dar, tasta poate fi inlocuita - vezi documentatia readline). Puneti fisierul in ~/.pystartup, iar variabila de mediu sa-l indice, cum ar fi in bash "export PYTHONSTARTUP=/max/home/itamar/.pystartup". Retineti ca PYTHONSTARTUP nu expandeaza "~", deci va trebui indicata intraga 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

87

88

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

89

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:
>>> sum = 0.0 >>> for i in range(10): ... sum += 0.1 ... fs>>> sum 0.99999999999999989

90

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

Aritmetica binar a n virgul a otant a are multe surprize de acest gen. Problema cu "0.1" este explicat a n sec tiunea a a altor surprize urm atoare, "Erori de reprezentare". Vezi : The Perils of Floating Point privind tratarea complet de acest gen. Cum s-ar spune la sfr sit: "nu este u sor de r aspuns". Totu si nu dispera ti din cauza virgulei 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:
>>> 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:

B.1. Erori de reprezentare

91

>>> 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!)

92

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

ANEXA

Istoricul produsului Python s i licen tierea


C.1 Istoricul produsului

Python a fost creat la nceputul anilor 1990 de c atre Guido van Rossum la Stichting Mathematisch Centrum (CWI, amas principalul autor al vezi http://www.cwi.nl/) din Olanda, ca succesor al limbajului ABC. Guido a r Python-ului, 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 (acum Zope Corporation ; vezi http://www.zope.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. Zope Corporation este unul din sponsorii PSF. (versiunile) Python sunt Open Source (vezi http://www.opensource.org/ pentru Toate lans arile pe pia ta 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 2.1.2 2.1.3 2.2.1 2.2.2 2.2.3 2.3 2.3.1 2.3.2 2.3.3 2.3.4 2.3.5 2.4 2.4.1 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 2.1.1 2.1.2 2.2 2.2.1 2.2.2 2.2.2 2.3 2.3.1 2.3.2 2.3.3 2.3.4 2.3 2.4 Year 1991-1995 1995-1999 2000 2000 2001 2001 2001 2001 2001 2002 2002 2002 2002 2002-2003 2002-2003 2002-2003 2003 2003 2004 2005 2004 2005 Owner CWI CNRI CNRI BeOpen.com CNRI PSF PSF PSF PSF PSF PSF PSF PSF PSF PSF PSF PSF PSF PSF PSF PSF PSF GPL compatible? yes yes no no no no yes yes yes yes yes yes yes yes yes yes yes yes yes yes yes yes

Not a: Compatibil GPL nu nseamn a c a Python este distribuit sub GPL. Toate licen tele Python, spre deosebire de
1 n

englez a : Intellectual Property

93

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 numero silor voluntari din exteriorul echipei, care lucrnd sub coordonarea lui Guido, au contribuit la apari tia acestor versiuni.

C.2

Terms and conditions for accessing or otherwise using Python


PSF LICENSE AGREEMENT FOR PYTHON 2.4.1

1. This LICENSE AGREEMENT is between the Python Software Foundation (PSF), and the Individual or Organization (Licensee) accessing and otherwise using Python 2.4.1 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.4.1 alone or in any derivative version, provided, however, that PSFs License Agreement and PSFs notice of copyright, i.e., Copyright 2001-2004 Python Software Foundation; All Rights Reserved are retained in Python 2.4.1 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.4.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 2.4.1. 4. PSF is making Python 2.4.1 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.4.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 2.4.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.4.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. 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.4.1, 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.

94

Anexa C. Istoricul produsului Python s i licen tierea

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. 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 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.

C.2. Terms and conditions for accessing or otherwise using Python

95

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 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 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.

C.3

Licenses and Acknowledgements for Incorporated Software

This section is an incomplete, but growing list of licenses and acknowledgements for third-party software incorporated in the Python distribution.

C.3.1

Mersenne Twister

The _random module includes code based on a download from http://www.math.keio.ac.jp/ ~matumoto/MT2002/emt19937ar.html. The following are the verbatim comments from the original code:

96

Anexa C. Istoricul produsului Python s i licen tierea

A C-program for MT19937, with initialization improved 2002/1/26. Coded by Takuji Nishimura and Makoto Matsumoto. Before using, initialize the state by using init_genrand(seed) or init_by_array(init_key, key_length). Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of its contributors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Any feedback is very welcome. http://www.math.keio.ac.jp/matumoto/emt.html email: matumoto@math.keio.ac.jp

C.3.2

Sockets

The socket module uses the functions, getaddrinfo, and getnameinfo, which are coded in separate source les from the WIDE Project, http://www.wide.ad.jp/about/index.html.

C.3. Licenses and Acknowledgements for Incorporated Software

97

Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS AS IS AND GAI_ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE FOR GAI_ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON GAI_ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN GAI_ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

C.3.3

Floating point exception control

The source for the fpectl module includes the following notice:

98

Anexa C. Istoricul produsului Python s i licen tierea

--------------------------------------------------------------------Copyright (c) 1996. \ | The Regents of the University of California. | | All rights reserved. | | | | Permission to use, copy, modify, and distribute this software for | | any purpose without fee is hereby granted, provided that this en| | tire notice is included in all copies of any software which is or | | includes a copy or modification of this software and in all | | copies of the supporting documentation for such software. | | | | This work was produced at the University of California, Lawrence | | Livermore National Laboratory under contract no. W-7405-ENG-48 | | between the U.S. Department of Energy and The Regents of the | | University of California for the operation of UC LLNL. | | | | DISCLAIMER | | | | This software was prepared as an account of work sponsored by an | | agency of the United States Government. Neither the United States | | Government nor the University of California nor any of their em| | ployees, makes any warranty, express or implied, or assumes any | | liability or responsibility for the accuracy, completeness, or | | usefulness of any information, apparatus, product, or process | | disclosed, or represents that its use would not infringe | | privately-owned rights. Reference herein to any specific commer| | cial products, process, or service by trade name, trademark, | | manufacturer, or otherwise, does not necessarily constitute or | | imply its endorsement, recommendation, or favoring by the United | | States Government or the University of California. The views and | | opinions of authors expressed herein do not necessarily state or | | reflect those of the United States Government or the University | | of California, and shall not be used for advertising or product | \ endorsement purposes. / --------------------------------------------------------------------/

C.3.4

MD5 message digest algorithm

The source code for the md5 module contains the following notice:

C.3. Licenses and Acknowledgements for Incorporated Software

99

Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software.

C.3.5

Asynchronous socket services

The asynchat and asyncore modules contain the following notice:


Copyright 1996 by Sam Rushing 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 Sam Rushing not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SAM RUSHING 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.

C.3.6

Cookie management

The Cookie module contains the following notice:

100

Anexa C. Istoricul produsului Python s i licen tierea

Copyright 2000 by Timothy OMalley <timo@alum.mit.edu> 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 Timothy OMalley not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Timothy OMalley DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Timothy OMalley 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.

C.3.7

Proling

The profile and pstats modules contain the following notice:


Copyright 1994, by InfoSeek Corporation, all rights reserved. Written by James Roskind Permission to use, copy, modify, and distribute this Python software and its associated documentation for any purpose (subject to the restriction in the following sentence) without fee is hereby granted, provided that the above copyright notice appears in all copies, and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of InfoSeek not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. This permission is explicitly restricted to the copying and modification of the software to remain in Python, compiled Python, or other languages (such as C) wherein the modified or derived code is exclusively imported into a Python module. INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION 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.

C.3.8

Execution tracing

The trace module contains the following notice:

C.3. Licenses and Acknowledgements for Incorporated Software

101

portions copyright 2001, Autonomous Zones Industries, Inc., all rights... err... reserved and offered to the public under the terms of the Python 2.2 license. Author: Zooko OWhielacronx http://zooko.com/ mailto:zooko@zooko.com Copyright 2000, Mojam Media, Inc., all rights reserved. Author: Skip Montanaro Copyright 1999, Bioreason, Inc., all rights reserved. Author: Andrew Dalke Copyright 1995-1997, Automatrix, Inc., all rights reserved. Author: Skip Montanaro Copyright 1991-1995, Stichting Mathematisch Centrum, all rights reserved.

Permission to use, copy, modify, and distribute this Python software and its associated documentation for any purpose without fee is hereby granted, provided that the above copyright notice appears in all copies, and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of neither Automatrix, Bioreason or Mojam Media be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission.

C.3.9

UUencode and UUdecode functions

The uu module contains the following notice:


Copyright 1994 by Lance Ellinghouse Cathedral City, California Republic, United States of America. 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 Lance Ellinghouse not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE 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. Modified by Jack Jansen, CWI, July 1995: - Use binascii module to do the actual line-by-line conversion between ascii and binary. This results in a 1000-fold speedup. The C version is still 5 times faster, though. - Arguments more compliant with python standard

102

Anexa C. Istoricul produsului Python s i licen tierea

C.3.10

XML Remote Procedure Calls

The xmlrpclib module contains the following notice:


The XML-RPC client interface is Copyright (c) 1999-2002 by Secret Labs AB Copyright (c) 1999-2002 by Fredrik Lundh By obtaining, using, and/or copying this software and/or its associated documentation, you agree that you have read, understood, and will comply with the following terms and conditions: Permission to use, copy, modify, and distribute this software and its associated documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appears in all copies, and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Secret Labs AB or the author not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR 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.

C.3. Licenses and Acknowledgements for Incorporated Software

103

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