Documente Academic
Documente Profesional
Documente Cultură
Cuprins
Lucrarea 2. Programarea în limbajul Python - lucrul cu fișiere și directoare ...................................1
2.1 Gestiunea fișierelor text în Python ...................................................................................2
2.2 Gestiunea fișierelor CSV ....................................................................................................8
2.3 Fișiere cu diacritice......................................................................................................... 16
2.4 Foldere şi interfaţa cu sistemul de operare ................................................................... 25
2.5 Bibliografie ..................................................................................................................... 29
Gestiunea fișierelor text în Python 2
Apoi, la prompter:
>>> fisier=open(r'Exemple\fisier1.txt')
>>> fisier
<open file 'Exemple\fisier1.txt', mode 'r' at 0x02DC6F98>
S-a deschis fișierul într-un buffer (zonă temporară de memorie) stocat în variabila fisier. La
afișarea variabilei se indică adresa bufferului și modul 'r' (read-only, modul implicit).
>>> fisier.name
'Exemple\\fisier1.txt'
- numele fișierului
>>> fisier.read()
'Ana are mere.\naaa\nxxx\n'
- returnează conținutul integral al fișierului sub forma unui string; codul \n reprezintă sfârșitul
de linie; a se observa că după citire fișierul se "termină" – un cursor imaginar parcurge tot conținutul
citit din fișier, de aceea următoarea tentativă de citire eșuează:
>>> fisier.readlines()
[]
Pentru a muta cursorul înapoi pe începutul fișierului:
>>> fisier.seek(0)
>>> fisier.readlines()
['Ana are mere.\n', 'aaa\n', 'xxx\n']
- de data aceasta conținutul e returnat ca o listă de linii
>>> fisier.seek(0)
>>> fisier.readline()
'Ana are mere.\n'
>>> fisier.readline()
'aaa\n'
>>> fisier.readline()
'xxx\n'
- de data aceasta fișierul s-a citit linie cu linie; ca și în cazul readlines, fiecare execuție a deplasat
un cursor imaginar prin conținutul fișierului, până la sfârșit; recitirea unor porțiuni de fișier presupune
din nou salturi la început sau la poziția dorită
Putem afişa conţinutul fişierului şi într-o manieră mai lizibilă, aşa cum ar arăta acesta în Notepad
sau alt editor de texte:
>>> fisier.seek(0)
>>> print fisier.read()
Ana are mere.
aaa
xxx
3 Lucrarea 2. Programarea în limbajul Python - lucrul cu fișiere și directoare
>>> fisier.seek(3)
>>> fisier.readline()
' are mere.\n'
- de data aceasta nu s-a revenit la început, ci la octetul 3; în fișierele text simple, ce folosesc
doar caractere ASCII, un octet e echivalent cu un caracter, de aceea linia începe doar de la caracterul cu
poziția 3, fără cuvântul "Ana"
>>> fisier.seek(-5,2)
>>> fisier.readline()
'xxx\n'
- acum seek a primit 2 argumente: al doilea este codul poziției de la care se numără saltul: dacă
lipsește se numără de la începutul fișierului, dacă e 1 se numără de la poziția curentă, dacă e 2 se
numără de la sfârșitul fișierului; așadar, are loc un salt cu 5 poziții înainte de finalul fișierului
>>> fisier.seek(0)
>>> fisier.readline(5)
'Ana a'
- după repoziționarea la început, readline s-a apelat cu argumentul 5, deci se citesc doar 5
octeți-caractere
>>> fisier.seek(0)
>>> fisier.read(10)
'Ana are me'
>>> fisier.read(10)
're.\naaa\nxx'
>>> fisier.read(10)
'x\n'
- după repoziționarea la început, read citește câte 10 octeți-caractere odată, mai puțin la sfârșit
când fișierul se termină
>>> fisier.seek(0)
>>> caractere=[x for rand in fisier for x in rand]
>>> caractere
['A', 'n', 'a', ' ', 'a', 'r', 'e', ' ', 'm', 'e', 'r', 'e', '.', '\n', 'a', 'a', 'a', '\n', 'x', 'x', 'x', '\n']
- lista caracterelor din fișier (nu e necesar să folosim for rand in fisier.readlines(), deoarece
obiectul-fișier este direct iterabil, adică poate fi parcurs direct, linie cu linie; in schimb la afisare e
necesar să folosim fisier.readlines() deoarece un obiect, chiar și iterabil, nu e identic cu o listă, nu are o
valoare afișabilă)
>>> fisier.seek(0)
>>> caractere=[x for rand in fisier for x in rand if x not in ' \n']
>>> caractere
['A', 'n', 'a', 'a', 'r', 'e', 'm', 'e', 'r', 'e', '.', 'a', 'a', 'a', 'x', 'x', 'x']
- lista caracterelor din fișier care nu sunt nici spații, nici final de linie; dacă se dorește obținerea
mulțimii caracterelor eliminând repetițiile, se poate converti lista în mulțime ca mai jos:
>>> set(caractere)
set(['A', 'a', 'e', 'm', 'n', 'r', 'x', '.'])
În continuare vom extrage toate cuvintele din fișier, prin două metode. Prima mai anevoioasă,
are rolul de a recapitula câteva funcții importante de prelucrare a stringurilor:
>>> fisier.seek(0)
>>> text=''.join(fisier)
( vorba de două apostroafe, nu o ghilimea!)
>>> text=text.replace('\n',' ')
>>> text
'Ana are mere. aaa xxx '
- cu join s-au unificat toate liniile într-un string unic, folosind șirul vid '' ca și delimitator; din nou,
s-a preferat exprimarea join(fisier) în loc de join(fisier.readlines()) deoarece obiectele-fișier sunt iterabile
Gestiunea fișierelor text în Python 4
>>> fisier.write("123")
- eroare, fișierul e read only deoarece deschiderea cu open are loc implicit în modul r, fapt care
se poate verifica după cum urmează
>>> fisier.mode
'r'
>>> fisier.close()
>>> fisier.closed
True
- s-a închis fișierul, apoi s-a verificat dacă fișierul e închis
>>> fisier=open(r'Exemple\fisier1.txt','r+')
- de data aceasta, fișierul e deschis în modul read-write, simbolizat prin r+, deci vor fi posibile
atât scrieri cât și citiri
>>> fisier.write('111')
>>> fisier.flush()
- scrierea are loc la poziția curentă, adică începutul fișierului; flush are rolul de a salva
modificarea în fișier; fără flush, salvarea efectivă a modificărilor va avea loc abia la închiderea fișierului
>>> fisier.readline()
' are mere.\n'
- se observă că write() a mutat cursorul, linia fiind citită după cele 3 caractere scrise
>>> fisier.seek(0)
>>> fisier.readline()
'111 are mere.\n'
- așa arată prima linie după operația de scriere
>>> fisier.seek(0,2)
- se deplasează cursorul la poziția zero începând de la sfârșitul fișierului, indicat prin codul 2
>>> fisier.write('222')
>>> fisier.flush()
>>> fisier.seek(0)
>>> fisier.readlines()
['111 are mere.\n', 'aaa\n', 'xxx\n', '222']
- se observă că noul string a fost scris la sfârșit
>>> fisier.seek(0)
>>> fisier.seek(len(fisier.readline())+1)
- poziționare la finalul primei linii
5 Lucrarea 2. Programarea în limbajul Python - lucrul cu fișiere și directoare
>>> fisier.write('3')
>>> fisier.flush()
>>> fisier.seek(0)
>>> fisier.readlines()
['111 are mere.\n', '3aa\n', 'xxx\n', '222']
- se observă că numărul 3 a fost scris la începutul liniei 2
>>> fisier.seek(0,2)
- poziționare la finalul fișierului
>>> fisier.writelines(['4444','5555'])
>>> fisier.flush()
>>> fisier.seek(0)
>>> fisier.readlines()
['111 are mere.\n', '3aa\n', 'xxx\n', '22244445555']
- numele funcției writelines() induce în eroare: NU se asigură scrierea mai multor rânduri, ci doar
concatenarea stringurilor din lista primită de writelines(); pentru a scrie mai multe rânduri trebuie ca
acele stringuri să conțină în mod explicit codul de final de rând, \n
>>> fisier.seek(0,2)
>>> fisier.writelines(['\n6666\n','77777\n'])
-s-au inserat finaluri de linie în fața primului string, adică la finalul curent al fișierului, și câte un
final de linie după fiecare string inserat
>>> fisier.flush()
>>> fisier.seek(0)
>>> fisier.readlines()
['111 are mere.\n', '3aa\n', 'xxx\n', '22244445555\n', '6666\n', '77777\n']
- se observă noile rânduri adăugate și finalizarea lor cu \n
>>> fisier.close()
>>> fisier=open(r'Exemple\fisier1.txt','a+')
- fisierul s-a redeschis în modul a+ care reprezintă read-append, cu scrieri posibile doar la finalul
fișierului!
>>> fisier.readlines()
['111 are mere.\n', '3aa\n', 'xxx\n', '22244445555\n', '6666\n', '77777\n']
>>> fisier.seek(0)
>>> fisier.write('8888')
>>> fisier.flush()
>>> fisier.seek(0)
>>> fisier.readlines()
['111 are mere.\n', '3aa\n', 'xxx\n', '22244445555\n', '6666\n', '77777\n', '8888']
- chiar dacă s-a făcut poziționarea cu seek(0) la început, operația write s-a aplicat la sfârșitul
fișierului!
>>> fisier.truncate(30)
>>> fisier.flush()
>>> fisier.seek(0)
>>> fisier.readlines()
['111 are mere.\n', '3aa\n', 'xxx\n', '22244']
- fișierul s-a trunchiat la primele 30 de caractere
>>> fisier.seek(-2,2)
- poziționare cu 2 caractere înaintea sfârșitului de fișier
>>> fisier.truncate()
>>> fisier.flush()
>>> fisier.seek(0)
>>> fisier.readlines()
['111 are mere.\n', '3aa\n', 'xxx\n', '222']
- fără argument, trunchierea se face la poziția curentă
>>> fisier=open(r'Exemple\fisier1.txt','w+')
>>> fisier.readlines()
[]
- la deschiderea în modul write-read, conținutul existent al fișierului se șterge! metoda e folosită
pentru a crea noi fișiere:
Gestiunea fișierelor text în Python 6
>>> f2=open(r'Exemple\fisier2.txt','w+')
- se poate verifica pe disc apariția noului fișier; și modurile w,a,a+ permit crearea de noi fișiere,
dacă primul argument din open indică un fișier inexistent; în absența semnului +, modurile w și a NU
permit utilizarea funcțiilor read/readline/readlines
O problemă ceva mai complicată e înlocuirea de text într-un fișier (tot în această categorie intră
și ștergerea de caractere, care de fapt e o înlocuire cu șirul vid). În modul read-write e posibilă scrierea
peste caracterele existente, dar nu și ștergerea, inserarea de text nou sau înlocuirea cu un text de
lungime diferită. Toate acestea necesită operații la nivel de string (replace), dar aceste operații nu sunt
disponibile și la nivel de fișier. În consecință, se apelează la următoarea succesiune de operații:
1. Deschiderea fișierului în mod read-write;
2. Citirea conținutului integral într-o listă de stringuri;
3. Aplicarea modificărilor asupra stringurilor din listă;
4. Trunchierea totală a conținutului fișierului (golirea sa);
5. Rescrierea stringurilor modificate în fișierul gol.
(practic e vorba de recrearea fișierului cu conținutul modificat)
>>> fisier.seek(0)
>>> fisier.readlines()
['ANA are mere.\n', 'aaaaa.\n']
- conținutul fișierului după rescrierea sa
O altă metodă de a scrie într-un fișier este cu ajutorul funcției print(). Print se folosește în mod
normal pentru afișare de mesaje. În exercițiile cu linia de comandă print() poate lipsi deoarece:
>>> print '1234'
e echivalent cu
>>> print('1234')
și cu
>>> '1234'
(totuși, print aduce beneficii în ce privește formatarea textului afișat – interpretează caractere
precum Tab și finalul de linie)
La prompter:
>>> fisier=open(r'Exemple\fisier.csv')
>>> fisiercsv=csv.reader(fisier)
>>> fisier.readlines()
['"A,n,a",30\n', '"M\n', 'a\n', 'r\n', 'i\n', 'a",70\n', '"Andrei a zis ""Hello"", apoi a plecat", 10\n']
>>> fisier.seek(0)
>>> [x for x in fisiercsv]
[['A,n,a', '30'], ['M\na\nr\ni\na', '70'], ['Andrei a zis "Hello", apoi a plecat', ' 10']]
Se observă că la accesarea prin fișierul original, se obține o listă de 7 rânduri; la accesarea prin
CSV, se obțin 3 înregistrări, prezența ghilimelelor face ca virgulele din numele Ana și salturile la rând nou
din numele Maria să NU fie considerate delimitatori, ci caractere normale; la fel, ghilimelele duble de la
Hello fac ca în datele finale acele ghilimele să apară în valori, nedublate, și fără a fi considerate
delimitatori.
La prompter:
>>> fisier=open(r'Exemple\fisier.csv')
>>> fisiercsv=csv.DictReader(fisier)
>>> [x for x in fisiercsv]
[{'Nume': 'Ana', 'sex': 'f', 'varsta': '30'},
{'Nume': 'Maria', 'sex': 'f', 'varsta': '40'},
{'Nume': 'Alin', 'sex': 'm', 'varsta': '20'}]
Dacă obiectul CSV e creat cu DictReader în loc de reader, datele din CSV sunt preluate ca o listă
de dicționare (în loc de matrice). Se observă că în fiecare dicționar, cheile au fost preluate de pe PRIMUL
RÂND al fișierului, iar valorile de pe restul rândurilor. Numărul de dicționare obţinute e egal cu numărul
de rânduri minus 1 (primul fiind considerat "cap de tabel"). Metoda este ideală când datele au o
structură tabelară (ex: au fost exportate din Excel). Dacă dorim să nu se considere primul rând cap de
tabel, putem prelua cheile din alte surse:
Ștergem capul de tabel din fisier.csv, rămânem cu datele:
"Ana",30,"f"
"Maria",40,"f"
"Alin",20,"m"
La prompter:
>>> fisier=open(r'Exemple\fisier.csv')
>>> captabel=['Nume','Varsta','Sex']
>>> fisiercsv=csv.DictReader(fisier,fieldnames=captabel)
>>> [x for x in fisiercsv]
[{'Nume': 'Ana', 'Sex': 'f', 'Varsta': '30'},
{'Nume': 'Maria', 'Sex': 'f', 'Varsta': '40'},
{'Nume': 'Alin', 'Sex': 'm', 'Varsta': '20'}]
- ordinea de afișare a elementelor într-un dicționar poate să difere de la o afișare la alta și poate
să difere de ordinea datelor din fișierul original, deoarece dicționarele nu sunt ordonate
Presupunem că înregistrările CSV au număr de valori diferit de capul de tabel. Modificăm fișierul
pentru a avea o înregistrare mai lungă și una mai scurtă:
"Ana",30,"f"
"Maria",40,"f","Cluj",2000
"Alin",20
La prompter:
>>> fisier=open(r'Exemple\fisier.csv')
>>> captabel=['Nume','Varsta','Sex']
>>> fisiercsv=csv.DictReader(fisier,fieldnames=captabel)
>>> [x for x in fisiercsv]
[{'Nume': 'Ana', 'Sex': 'f', 'Varsta': '30'},
{'Nume': 'Maria', 'Sex': 'f', None: ['Cluj', '2000'], 'Varsta': '40'},
{'Nume': 'Alin', 'Sex': None, 'Varsta': '20'}]
- s-a creat cheia None pentru valorile în plus și valoarea None pentru valorile în minus; eventual
și acestora li se pot aloca valori la momentul accesării datelor, ca mai jos:
>>> fisier=open(r'Exemple\fisier.csv')
>>> captabel=['Nume','Varsta','Sex']
>>> cheiesupl='Alte Date'
>>> valoareimpl='Nu se stie'
>>>fisiercsv=csv.DictReader(fisier,fieldnames=captabel,restkey=cheiesupl,restval=valoareimpl)
>>> [x for x in fisiercsv]
[{'Nume': 'Ana', 'Sex': 'f', 'Varsta': '30'},
{'Alte Date': ['Cluj', '2000'], 'Nume': 'Maria', 'Sex': 'f', 'Varsta': '40'},
{'Nume': 'Alin', 'Sex': 'Nu se stie', 'Varsta': '20'}]
11 Lucrarea 2. Programarea în limbajul Python - lucrul cu fișiere și directoare
- s-a alocat o cheie suplimentară pt valorile în plus și o valoare implicită pt valorile în minus
Am amintit deja că fișierele CSV nu sunt standardizate. Spre exemplu, Excel 2007 poate salva
astfel de fișiere în mai multe formate, cu delimitatori diferiți:
Construim în Excel Tabelul:
Nume|Varsta|Sex
Ion|20|m
/An,drei/|5|m
Al"ina|66|f
>>> fisier2.readlines()
['Nume\tVarsta\tSex\n', 'Ion\t20\tm\n', '"An,drei"\t5\tm\n', '"Ali""na"\t66\tf\n']
(separator valori=Tab, cu codul \t, separator de linii=\n, caracter de încadrare=ghilimelele; din
nou Excel a dublat ghilimeaua din interiorul valorii)
>>> fisier3.readlines()
['Nume|Varsta|Sex\n', 'Ion|20|m\n', '/An,drei/|5|m\n', 'Al"ina|66|f\n']
(separator valori=|, separator de linii=\n, caracter de încadrare a valorilor = /)
(nu mai e necesară dublarea ghilimelei, deoarece și-a pierdut funcția de încadrare a valorilor; în
acest fișier, dublarea ar trebui aplicată doar la /, acesta fiind noul caracter de încadrare; nici măcar
prezența lui / nu ar fi necesară, deoarece virgula din numele lui Andrei nu mai are funcție de separator)
Observații:
Gestiunea fișierelor CSV 12
în cele 3 exemple s-au folosit diverși delimitatori; singurul rămas fix e finalul de linie, deoarece
Python 2.7 nu acceptă la citire alt final de linie(pe de altă parte permite să fie modificat când
fișierul e creat din Python, deci poate fi considerat un bug);
desigur, denumirea de fișier CSV devine improprie când nu mai e folosită virgula (de aceea
ultimele 2 sunt salvate cu extensia TXT), dar în limbajul curent orice fișier inspirat de structura
CSV e considerat ca fiind "de tip CSV".
>>> fisier3.seek(0)
>>> csv3=csv.reader(fisier3,delimiter='|',quotechar='/')
>>> [x for x in csv3]
[['Nume', 'Varsta', 'Sex'], ['Ion', '20', 'm'], ['An,drei', '5', 'm'], ['Al"ina', '66', 'f']]
- pentru a treia variantă nu există un dialect predefinit; Python permite să se creeze unul cu
ajutorul clasei Dialect, dar cel mai facil e să se precizeze direct separatorul de valori (delimiter) și
caracterul de încadrare (quotechar); separatorul de linii, cum am precizat deja, nu poate fi modificat la
citirea de date
Aceleași metode de indicare a dialectului se pot folosi și dacă datele sunt extrase sub formă de
dicționare (vezi exemplele cu DictReader în loc de reader)
>>> csv3.dialect.delimiter
'|'
>>> csv3.dialect.quotechar
'/'
- prin intermediul clasei Dialect se pot obține informații despre componentele dialectului curent;
acestea nu sunt importante la citirea de date, deoarece separatorii sunt eliminați după extragerea
datelor, dar sunt importante la salvarea de date, deoarece vor fi inserați în fișier
Observații: Python oferă clasa Sniffer, prin care se poate analiza conținutul unui fișier pentru a deduce
dialectul. Rezultatele însă sunt de acuratețe scăzută, deducția făcându-se pe baza numărului de apariții
a fiecărui caracter pe o linie (deci un caracter care apare la fel de des ca separatorul de valori, poate fi
1
Dacă în Control Panel e setat specificul regional Romanian, în loc de virgulă e punct-virgulă!
13 Lucrarea 2. Programarea în limbajul Python - lucrul cu fișiere și directoare
Pentru a putea salva date CSV într-un fişier, acesta trebuie să fie deschis într-un mod care
permite scrierea. În exemplul următor se foloseşte modul write-read prin care se şi creează fişierul:
>>> fisier=open(r'Exemple\fisiernou.csv','w+')
>>> obiectCSV=csv.writer(fisier)
- definirea obiectului ce se va ocupa de salvarea datelor în fişier
>>> date=['Ana',20,'x,x,x','Andrei a spus "Hello" si a plecat']
- am creat o listă cu 4 elemente, ultimele două conţinând şi separatori
>>> obiectCSV.writerow(date)
- spre deosebire de fisier.write() care poate adăuga doar stringuri în fişier, funcţia writerow
poate primi ca argument structuri de date pe care le converteşte în text, utilizând regulile dialectului
CSV curent. Implicit este dialectul Excel, ce foloseşte virgula, finalul de linie şi ghilimelele
>>> fisier.flush()
>>> fisier.seek(0)
>>> fisier.readlines()
['Ana,20,"x,x,x","Andrei a spus ""Hello"" si a plecat"\r\n']
- fişierul poate fi deschis şi în Excel sau Notepad pentru a observa forma în care s-au salvat
datele; se poate observa că writerow s-a ocupat şi de adăugarea finalului de linie, aici \r\n, şi de
dublarea ghilimelelor la nevoie (observație: \r este codul de final de linie pentru Macintosh, majoritatea
programelor salvează ambele coduri - \r\n - la final de linie pentru a se asigura că va funcţiona pe orice
sistem de operare)
>>> listatuple=[('Ion','b',30),('Alin','b',20)]
>>> fisier.seek(0)
>>> obiectCSV.writerows(listatuple)
- de data aceasta se foloseşte writerows(), pentru a scrie mai multe înregistrări; fiecare element
al listei e convertit într-o înregistrare, începând cu poziţia curentă, începutul, deci parte din conţinut se
va suprascrie; ca şi writerow(), funcţia se ocupă de inserarea delimitatorilor conform cu dialectul Excel
>>> fisier.flush()
>>> fisier.seek(0)
>>> fisier.readlines()
['Ion,b,30\r\n',
'Alin,b,20\r\n',
'a spus ""Hello"" si a plecat"\r\n]
>>> obiectCSV.dialect.delimiter
','
>>> obiectCSV.dialect.quotechar
'"'
>>> obiectCSV.dialect.lineterminator
'\r\n'
- s-au afişat separatorii dialectului
>>> dictionar={'XX':11,'YY':22}
>>> fisier.seek(0,2)
>>> obiectCSV.writerows(dictionar)
>>> fisier.flush()
>>> fisier.seek(0)
>>> fisier.readlines()
['Ion,b,30\r\n',
'Alin,b,20\r\n',
'a spus ""Hello"" si a plecat"\r\n',
'Y,Y\r\n',
'X,X\r\n']
- s-au scris DOAR cheile din dicţionar; pentru valori, se lucrează cu dictionar.values(); pentru a
scrie întreg dicţionarul se lucrează cu DictWriter
>>> fisier.seek(0)
>>> fisier.truncate()
>>> fisier.flush()
Gestiunea fișierelor CSV 14
Observații:
spre deosebire de DictReader, la scriere e OBLIGATORIU să se specifice capul de tabel, sub forma
unei secvenţe de stringuri;
apoi, toate dicţionarele salvate în fişier TREBUIE să aibă chei identice cu capul de tabel!
dacă dicţionarele salvate în fişier au chei în minus faţă de capul de tabel, se inserează valoarea
implicită declarată prin restval;
dacă dicţionarele salvate au chei în plus faţă de capul de tabel, în mod implicit e eroare (dar
eroarea se poate dezactiva);
dialectul implicit este tot Excel.
>>> obiectCSV2.writerow(dictionar)
- eroare! dicţionarul conţine cheia Sex, pentru care nu s-a definit o coloană în capul de tabel!
dacă se doreşte ignorarea elementelor pentru care nu s-au pregătit coloane în tabel, obiectul CSV se
creează cu un argument în plus:
>>>obiectCSV2=csv.DictWriter(fisier,['Nume','Nota','LocNasterii'],restval=valimplicita,extrasaction='ignore',dialect='excel-tab')
- extrasaction va indica ignorarea cheilor suplimentare, apoi am schimbat şi dialectul în Excel
Tab, pentru a salva Taburi în loc de virgule
>>> obiectCSV2.writeheader()
>>> obiectCSV2.writerow(dictionar)
- writeheader() salvează capul de tabel, writerow() salvează valorile din dicţionar
>>> fisier.flush()
>>> fisier.seek(0)
>>> fisier.readlines()
['Nume\tNota\tLocNasterii\r\n',
'Ion\t4\tNu se stie\r\n']
- \t sunt codurile pentru Taburi; în Notepad fişierul arată astfel:
Desigur, ideal e ca toate dicţionarele salvate în fişierul CSV să aibă aceleaşi chei, atât între ele cât
şi faţă de capul de tabel declarat cu DictWriter. În acest caz, DictWriter îşi poate lua capul de tabel direct
din dicţionare:
>>> listadictionare=[]
>>> listadictionare.append({'Nume':'Ion','Nota':4,'Sex':'b'})
>>> listadictionare.append({'Nume':'Maria','Nota':10,'Sex':'f'})
>>> listadictionare.append({'Nume':'Alin','Nota':3,'Sex':'b'})
>>> fisier.seek(0)
>>> fisier.truncate()
>>> fisier.flush()
- am golit fişierul şi am iniţializat o listă de dicţionare cu aceleaşi chei
>>> obiectCSV2=csv.DictWriter(fisier,listadictionare[0].keys(),quotechar='/',delimiter='|',lineterminator='.\n',quoting=csv.QUOTE_ALL)
- capul de tabel s-a preluat de la cheile primului dicţionar; nu s-au mai luat măsuri pentru
nepotrivirea între chei şi capul de tabel; s-a definit un dialect nou, cu / pe post de ghilimele, | pe post de
virgulă, punct la finalul fiecărei linii, şi opţiunea QUOTE_ALL activă – prin aceasta, toate valorile vor fi
încadrate cu caracterul ce a preluat funcţia ghilimelelor
>>> fisier.seek(0)
>>> fisier.truncate()
>>> fisier.flush()
>>> obiectCSV2.writerows(listadictionare)
>>> fisier.flush()
15 Lucrarea 2. Programarea în limbajul Python - lucrul cu fișiere și directoare
>>> fisier.seek(0)
>>> fisier.readlines()
['/Ion/|/4/|/b/.\n',
'/Maria/|/10/|/f/.\n',
'/Alin/|/3/|/b/.\n']
În Notepad:
/Ion/|/4/|/b/.
/Maria/|/10/|/f/.
/Alin/|/3/|/b/.
Toate opţiunile de modificare a dialectului se aplică identic şi dacă folosim csv.writer în loc de
csv.DictWriter.
Toate opţiunile privind modul de deschidere a fişierelor rămân valabile la CSV:
modul r+ permite şi citire şi scriere, DOAR dacă fişierul există deja;
modul w+ permite şi citire şi scriere, DAR goleşte fişierul în caz că există şi îl creează dacă nu
există;
modul a+ permite şi citire şi scriere, NU afectează conţinutul existent, scrierea se face la sfârşit
indiferent de poziţionarea cu seek.
modul r permite doar citire, fişierul trebuie să existe;
modul w permite doar scriere, creează fişierul şi îl distruge dacă exista deja;
modul a permite doar scriere fără a distruge fişierul în caz că exista deja, scrierea se face la
sfârşit.
La acestea se adaugă modurile binare: r+b,rb, etc. Acestea se folosesc pentru a lucra cu fişiere
binare (altele decât de tip text) în care se lucrează la nivel de octet. Funcţiile cu care se lucrează sunt
aceleaşi.
Fișiere cu diacritice 16
>>> a=u'âî'
>>> a
u'\xe2\xee'
>>> print a
âî
Observație: Exerciţiile următoare sunt testate pe specificul local English US. Asta înseamnă că nu se pot
tasta diacritice în linia de comandă (dar se pot tasta în programe şi module, acestea solicitând la
salvarea unui cod sursă cu diacritice setarea UTF-8 printr-un comentariu inserat automat la începutul
modulului!). De aceea în linia de comandă se vor tasta codurile caracterelor dorite şi nu caracterele
propriu-zise. Trecerea pe specificul local românesc (cu tastatură Romanian Legacy) va permite tastarea
de diacritice însă pe unele versiuni de Windows poate apare o conversie eronată a caracterelor ș și ț la
afișare. Specificul local se selectează în Control Panel – Region and Language – Administrative – Change
System Locale.
Python poate deschide fișiere cu diacritice prin intermediul modulului codecs.py care asigură
conversia între mai multe sisteme de codificare a caracterelor (şi nu doar caractere, ci şi sunet, video
etc). Pe de altă parte, modulul csv dă eroare dacă întâlneşte caractere Unicode, dar poate lucra cu
sistemul de codificare UTF-8 care e compatibil cu ASCII (pentru caracterele de bază are aceleași coduri,
pentru restul are coduri care vor fi interpretate ca grupuri de caractere ASCII). Conversiile se pot realiza
conform exerciţiilor de mai jos:
>>> x=u'\u0103'
>>> y=u'\u021a'
- s-au iniţializat x şi y cu două caractere cu diacritice; datorită setării specificul local englez nu se
pot tasta diacritice în IDLE și am indicat codurile Unicode
>>> x
u'\u0103'
>>> y
u'\u021a'
>>> print x
17 Lucrarea 2. Programarea în limbajul Python - lucrul cu fișiere și directoare
ă
>>> print y
Ț
- se observă afişarea diferită cu numele variabilei faţă de folosirea lui print
În continuare efectuăm conversii DIN UNICODE ÎN UTF8 – acestea sunt necesare ÎNAINTE de
salvarea datelor într-un fişier:
>>> xUTF=x.encode('UTF-8')
>>> xUTF
'\xc4\x83'
- aşa arată codul UTF, comparativ cu codul Unicode de mai sus
>>> print xUTF
ă
- UTF8 permite ca aceste caractere să fie folosite în loc de ă, în programele care nu pot lucra cu
Unicode (pe specificul local Romanian, afişarea e corectă, căci Windows se ocupă de conversia în
Unicode dar numai LA AFIŞARE!)
>>> yUTF=y.encode('UTF-8')
>>> y
u'\u021a'
>>> yUTF
'\xc8\x9a'
>>> print yUTF
Èš
(echivalentul UTF-8 pentru Ţ; specificul local Romanian va afişa Čš, datorită problemelor
Windows legate de litera Ţ)
În continuare efectuăm conversii DIN UTF8 ÎN UNICODE: - acestea sunt necesare DUPĂ citirea
datelor dintr-un fişier, pentru a le putea manipula direct în format Unicode:
>>> xUni=xUTF.decode('UTF-8')
>>> xUni
u'\u0103'
>>> print xUni
ă
>>> yUni=yUTF.decode('UTF-8')
>>> yUni
u'\u021a'
>>> print yUni
Ț
Funcţiile decode şi encode pot efectua conversii la nivel de string. Dacă stringurile apar într-o
structură de date, conversia devine mai anevoioasă:
>>> listaUni=[x,y]
>>> listaUni
[u'\u0103', u'\u021a']
>>> listaUTF=[i.encode('UTF-8') for i in listaUni]
>>> listaUTF
['\xc4\x83', '\xc8\x9a']
Modulul codecs oferă unele funcţii care facilitează conversia listelor (fără a le mai parcurge
explicit), dar rezultatul conversiei are un comportament mai…ciudat:
>>> import codecs
>>> dateUTF=codecs.iterencode(listaUni,'UTF-8')
>>> [x for x in dateUTF]
['\xc4\x83', '\xc8\x9a']
>>> [x for x in dateUTF]
[]
>>> dateUTF
Fișiere cu diacritice 18
Observații: A doua parcurgere a variabilei dateUTF dă rezultat vid, iar conţinutul variabilei dateUTF nu
poate fi afişat în mod direct! Asta deoarece funcţia iterencode() (şi în general funcţiile ale căror nume
încep cu iter) NU returnează liste, ci obiecte de tip iterator. Mai multe detalii despre iteratori se vor
discuta în capitolul dedicat funcțiilor, deocamdată e important doar faptul că un iterator poate fi parcurs
O SINGURĂ DATĂ. Pentru a conserva datele unui iterator, acesta trebuie convertit în listă:
>>> dateUTF=codecs.iterencode(listaUni,'UTF-8')
>>> listaUTF=list(dateUTF)
>>> [x for x in listaUTF]
['\xc4\x83', '\xc8\x9a']
>>> [x for x in listaUTF]
['\xc4\x83', '\xc8\x9a']
- linia boldată asigură conversia iteratorului în listă, ceea ce permite, în continuare, accesarea
normală a datelor
Aşadar iterdecode şi iterencode sunt utile la a converti secvenţe (şiruri de valori) dar NU şi
structuri de date mai complexe:
pentru matrici, se converteşte pe rând fiecare linie, apoi liniile se grupează cu un FOR;
pentru dicţionare, se converteşte lista cheilor, apoi lista valorilor, apoi rezultatele sunt
împachetate cu zip() şi reconvertite în dicţionar cu dict():
Presupunând că există o matriceUTF şi un dicţionarUTF:
>>> matriceUni=[list(codecs.iterdecode(rand,'UTF-8')) for rand in matriceUTF]
>>> dictionarUni=dict((zip(codecs.iterdecode(dictionarUTF,'UTF-8'), codecs.iterdecode(dictionarUTF.values(),'UTF-8'))))
(după cum se vede, s-a rezolvat şi problema conversiei iteratorului: list(), respectiv dict(zip())
asigură conversiile necesare în cele două cazuri)
Pentru a manevra fișiere text (inclusiv CSV) fără a pierde diacriticele, trebuie avute în vedere
două categorii de aspecte:
XML:
<?xml version="1.0" encoding="UTF-8"?>
HTML:
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
(aceasta nu e o cerinţă foarte importantă, majoritatea browserelor moderne presupun implicit
că documentul primit e UTF-8 sau detectează acest lucru din modul în care a fost salvat fişierul, de la
punctul 1; următoarele cerinţe sunt însă importante, ele afectând cel mai des afişarea incorectă a
diacriticelor în browsere!)
3. Dacă documentul XML/XHTML este generat dinamic de la server, trebuie modificat și antetul
HTTP; dacă nu avem posibilități de configurare a serverului, se face modificarea HTTP la nivel de pagină;
de exemplu, în PHP:
4. Dacă documentul conţine diacritice preluate din baza de date (MySQL), şi baza de date va
trebui convertită în UTF-8; phpmyadmin oferă astfel de opţiuni sau se poate folosi o comandă SQL:
ALTER TABLE tabel CONVERT TO CHARACTER SET UTF8
La salvare din Notepad, se folosește Save As și după precizarea numelui se selectează opțiunea
Encoding: UTF-8. Dacă nu se modifică sistemul de codare, Notepad avertizează că unele diacritice se vor
pierde.
Fișiere cu diacritice 20
>>> fisdiac2.seek(0)
>>> print fisdiac2.read()
Nume, Vârstă, Sex
Èšicleanu Maria, 20, femeiesc
Pașcu Andrei, 30, bărbătesc
- textul rămas în UTF-8 e afișat incorect – se poate observa că fiecare caracter cu diacritice e
substituit cu 2 caractere ASCII; reamintim că UTF-8 înlocuiește caracterele Unicode cu grupuri de 2-4
caractere ASCII pentru a conserva codurile chiar și în programe care nu pot afișa Unicode; pe specificul
local Romanian şi aceste date sunt afişate CORECT, datorită conversiei automate asigurate de Windows
LA AFIŞARE; totuși, în programele Python nu trebuie să ne bazăm pe acest lucru!
În acest exemplu conversia UTF->Unicode s-a făcut chiar la deschiderea fișierului. În cazul CSV
acest lucru nu e posibil, deoarece CSV nu poate lucra cu Unicode și trebuie să lucreze tot cu UTF-8. În
astfel de cazuri conversia la Unicode se amână până când fișierul a trecut de filtrul CSV. Extragem datele
CSV tot din obiectele-fișier precedente:
>>> import csv
>>> csvdiac1=csv.reader(fisdiac1)
>>> csvdiac2=csv.reader(fisdiac2)
- ambele obiecte-fișier s-au convertit cu success în obiecte CSV; eroarea va apare la afișare!
>>> fisdiac1.seek(0)
>>> fisdiac2.seek(0)
>>> print [x for x in csvdiac1]
- eroare UnicodeError! primul obiect CSV, care a primit datele direct în Unicode, NU poate fi
accesat
>>> print [x for x in csvdiac2]
[['\xef\xbb\xbfNume', ' V\xc3\xa2rst\xc4\x83', ' Sex'], ['\xc8\x9aicleanu Maria', ' 20', ' femeiesc'], ['Pa\xc8\x99cu Andrei', ' 30',
'b\xc4\x83rb\xc4\x83tesc']]
- în al doilea caz, al fișierului rămas în UTF-8, datele au putut fi accesate prin CSV
>>> fisd.read()
u'\ufeffNume, V\xe2rst\u0103, Sex\r\n\u021aicleanu Maria, 20, femeiesc\r\nPa\u0219cu Andrei, 30, b\u0103rb\u0103tesc'
>>> textdiac=u'\u0219al\u0103u'
- datorită imposibilității de a tasta diacritice în IDLE, stocăm textul cu diacritice cu ajutorul codurilor
Unicode: \u0219=ş,\u0103=ă, coduri ce pot fi citite din datele de mai sus; reamintim că acest bug nu
afectează programele şi modulele Python ci numai linia de comandă; reamintim că stringurile Unicode,
indiferent că au diacritice sau coduri de diacritice, se prefixează cu litera u; reamintim că specificul
Romanian permite tastarea directă în IDLE: textdiac=u'şalău' dar pot apare probleme cu litera ş!)
>>> print textdiac
șalău
(specificul Romanian va afişa ºalãu datorită problemelor Windows legate de codiţele de la ş şi)
>>> fisd.seek(0,2)
- ne deplasăm la finalul fişierului pentru a nu scrie peste conţinutul existent
>>> fisd.write(textdiac)
>>> fisd.flush()
>>> fisd.seek(0)
>>> fisd.read()
u'\ufeffNume, V\xe2rst\u0103, Sex\r\n\u021aicleanu Maria, 20, femeiesc\r\nPa\u0219cu Andrei, 30, b\u0103rb\u0103tesc\u0219al\u0103u'
Acest exemplu reflectă simplitatea cu care se salvează diacriticele dacă fişierul e deschis cu
codecs.open în loc de open. Codecs, prin opţiunea encoding UTF-8, asigură conversia AUTOMATĂ a
oricăror caractere citite din fişier (de la UTF la Unicode) ŞI a celor scrise în fişier (de la Unicode la UTF).
Dacă nu se foloseşte deschiderea prin codecs, aceste conversii trebuie făcute EXPLICIT:
>>> fisd=open(r'Exemple\diacritice.txt','r+')
>>> fisd.read()
'\xef\xbb\xbfNume, V\xc3\xa2rst\xc4\x83, Sex\n\xc8\x9aicleanu Maria, 20, femeiesc\nPa\xc8\x99cu Andrei, 30,
b\xc4\x83rb\xc4\x83tesc\xc8\x99al\xc4\x83u'
- deschiderea s-a făcut direct, conţinutul a rămas codat în UTF-8; nu îl decodăm deoarece nu
dorim să afişăm nimic din el, ci să adăugăm la el
>>> textdiac=u'...al doilea \u0219al\u0103u\n'
>>> print textdiac
...al doilea șalău
- textul ce va fi adăugat, cu Enter la sfârşit
>>> textdiacUTF=textdiac.encode('UTF-8')
- textul e convertit in UTF 8 pentru a putea fi salvat; dacă e salvat fără să fie codat, se obţine
eroare
>>> fisd.seek(0,2)
>>> fisd.write(textdiacUTF)
>>> fisd.flush()
>>> fisd.seek(0)
>>> fisd.read()
'\xef\xbb\xbfNume, V\xc3\xa2rst\xc4\x83, Sex\n\xc8\x9aicleanu Maria, 20, femeiesc\nPa\xc8\x99cu Andrei, 30,
b\xc4\x83rb\xc4\x83tesc\xc8\x99al\xc4\x83u...al doilea \xc8\x99al\xc4\x83u\n'
- se observă adăugarea la sfârşit, sau mai clar în Notepad:
Dacă fişierul are structura CSV se procedează la fel, realizând codarea UTF înainte de scrierea
datelor:
>>> fisd=open(r'Exemple\diacritice.txt','a+')
- fişierul s-a deschis în modul append-read pentru a scrie automat la sfârşit
>>> fisCSV=csv.writer(fisd,delimiter=':',lineterminator='...\n')
- s-a definit un dialect CSV cu : în loc de virgulă şi puncte de suspensie la final de linii
>>> matriceUnicode=[[u'\u0219al\u0103u' for i in range(3)] for j in range(3)]
>>> matriceUnicode
[[u'\u0219al\u0103u', u'\u0219al\u0103u', u'\u0219al\u0103u'],
[u'\u0219al\u0103u', u'\u0219al\u0103u', u'\u0219al\u0103u'],
[u'\u0219al\u0103u', u'\u0219al\u0103u', u'\u0219al\u0103u']]
- am generat o matrice care să conţină cuvântul şalău de 3x3 ori; încercarea de a scrie aceste
date prin CSV eşuează
>>> matriceUTF=[[x.encode('UTF-8') for x in rand] for rand in matriceUnicode]
- am convertit matricea în UTF-8
(sau, prin codecs:
import codecs (dacă nu era importat)
matriceUTF=[list(codecs.iterencode(rand,'UTF-8')) for rand in matriceUnicode] )
>>> fisCSV.writerows(matriceUTF)
- am scris matricea la finalul fişierului
>>> fisd.flush()
Fișiere cu diacritice 24
>>> fisd.seek(0)
>>> fisd.readlines()
['\xef\xbb\xbfNume, V\xc3\xa2rst\xc4\x83, Sex\n','\xc8\x9aicleanu Maria, 20, femeiesc\n', 'Pa\xc8\x99cu Andrei, 30,
b\xc4\x83rb\xc4\x83tesc\xc8\x99al\xc4\x83u...al doilea \xc8\x99al\xc4\x83u\n',
'\xc8\x99al\xc4\x83u:\xc8\x99al\xc4\x83u:\xc8\x99al\xc4\x83u...\n', '\xc8\x99al\xc4\x83u:\xc8\x99al\xc4\x83u:\xc8\x99al\xc4\x83u...\n',
'\xc8\x99al\xc4\x83u:\xc8\x99al\xc4\x83u:\xc8\x99al\xc4\x83u...\n']
În Notepad:
Nume, Vârstă, Sex
Țicleanu Maria, 20, femeiesc
Pașcu Andrei, 30, bărbătescșalău...al doilea șalău
șalău:șalău:șalău...
șalău:șalău:șalău...
șalău:șalău:șalău...
- am boldat datele adăugate ultima dată
Concluzii:
diacriticele trebuie să fie în format UTF-8 când sunt pe disc (în fişiere);
diacriticele trebuie să fie în format Unicode când sunt în RAM (în timpul procesării, în timpul
afişării)
Pentru a conserva diacriticele în fișiere accesate din Web (presupunând că acestea sunt livrate
în format UTF-8), programele Python trebuie:
să convertească conținutul fișierelor în Unicode cât mai devreme cu putință:
o imediat după deschiderea simplă cu open() sau…
o …dacă se dorește accesare prin CSV, imediat după accesarea datelor cu csv.reader();
să reconvertească din Unicode în UTF-8 cât mai târziu cu putință:
o chiar înainte de scrierea datelor în fișier cu write,writelines sau…
o …dacă scrierea se face prin CSV, chiar înainte de executarea writerow, writerows, etc.
Dacă fişierul se dechide cu codecs.open în loc de open, nu mai e necesară conversia, fiind
asigurată atât la citire cât şi la scriere (dar astfel de fişiere nu pot fi accesate prin CSV).
25 Lucrarea 2. Programarea în limbajul Python - lucrul cu fișiere și directoare
>>> os.getcwd()
'C:\\Python27\\Exemple'
>>> os.rename('foldernou','altfolder')
- s-a schimbat numele lui foldernou; operaţia funcţionează identic pentru fişiere
>>> fisier=open(r'altfolder\fis.txt','w+')
>>> fisier.write('xxxx')
>>> fisier.close()
>>> os.rename(r'altfolder\fis.txt',r'altfolder\fis2.csv')
- s-a creat un fişier al cărui nume a fost apoi schimbat; există şi funcţia renames() care schimbă
denumirea unui lanţ de foldere
Observații: Fiind vorba de o interfaţă cu sistemul de operare, modulul os asigură şi accesul la fişiere dar
la un nivel mai scăzut (mai primitiv şi în mod binar) decât funcţia open(). Funcţii ca os.open(), os.fdopen()
asigură deschiderea de fişiere, os.read() şi os.write() asigură operaţii la nivel de octet.
>>> os.rmdir('altfolder')
- eroare! folderele trebuie să fie goale pt. a fi şterse
>>> os.remove(r'altfolder\fis2.csv')
- s-a şters fişierul
>>> os.rmdir('altfolder')
- s-a şters folderul
>>> os.tempnam()
Warning (from warnings module):
File "__main__", line 1
RuntimeWarning: tempnam is a potential security risk to your program
'C:\\Users\\2\\AppData\\Local\\Temp\\2'
- se afişează calea folderului rezervat pentru fişiere temporare; fişierele temporare se creează şi
gestionează cu modulul tempfiles
>>> os.mkdir('foldernou')
>>> fisier=open(r'foldernou\fis.html','w+')
>>> fisier.write('<font color=red>xxxx</font>')
>>> fisier.close()
- s-a creat un fişier HTML
>>> os.startfile(r'foldernou\fis.html')
- startfile() e echivalentul unui dublu clic pe fişier, ar trebui să deschidă fişierul în browser
>>> os.startfile(r'foldernou\fis.html','edit')
>>> os.startfile(r'foldernou\fis.html','print')
- dacă al doilea argument e edit sau print se execută programul responsabil cu editarea sau
printarea fişierului
>>> os.startfile(r'foldernou','explore')
>>> os.startfile(r'foldernou','find')
- dacă folosim startfile() pe foldere, se pot executa operaţiile explore şi search pe folder
>>> os.system('cmd')
- funcţia system transferă argumentul spre sistemul de operare, care îl va interpreta ca pe o
comandă directă, în genul celor care se tastează în caseta Run din Windows; comanda cmd va lansa în
execuţia linia de comandă Windows
Următorii indicatori oferă informaţii despre cum trebuie scrise căile în Python (acestea diferă de
la un sistem de operare la altul). Rezultatele aici indicate sunt pentru Windows:
>>> os.curdir
'.'
- simbolul folosit în loc de cale pentru a indica folderul curent
>>> os.pardir
'..'
27 Lucrarea 2. Programarea în limbajul Python - lucrul cu fișiere și directoare
O funcţie puternică oferită de os este walk(), pentru parcurgerea recursivă a unui întreg arbore
de foldere:
>>> os.chdir('foldernou')
>>> os.makedirs(r'folder1\folder11\folder111')
>>> os.makedirs(r'folder1\folder11\folder112')
>>> os.makedirs(r'folder1\folder12\folder121')
- în foldernou am creat un arbore de 6 foldere, împărţite pe 3 nivele
>>> f1=open(r'folder1\f1.txt','w+')
>>> f12=open(r'folder1\folder12\f12.txt','w+')
>>> f121=open(r'folder1\folder12\folder121\f121.txt','w+')
>>> f111=open(r'folder1\folder11\folder111\f111.txt','w+')
- am creat 4 fişiere în diverse locuri din arbore
>>> [x for x in os.walk('folder1')]
[('folder1', ['folder11', 'folder12'], ['f1.txt']),
('folder1\\folder11', ['folder111', 'folder112'], []),
('folder1\\folder11\\folder111', [], ['f111.txt']),
('folder1\\folder11\\folder112', [], []),
('folder1\\folder12', ['folder121'], ['f12.txt']),
('folder1\\folder12\\folder121', [], ['f121.txt'])]
Principala utilizare a funcţiei walk() apare în ciclurile For care execută o operaţie pentru fiecare
tuplu găsit de walk(). Aceste operaţii pot fi chiar de ştergere/redenumire/modificare caz în care
următorul tuplu accesat de walk va REFLECTA modificările făcute la precedentul pas. În exemplul
următor parcurgem arborele din folder1 şi modificăm extensia la toate fişierele din txt în csv:
>>> f1.close()
>>> f12.close()
>>> f121.close()
>>> f111.close()
Foldere şi interfaţa cu sistemul de operare 28
Explicații:
pentru fiecare fişier i s-a obţinut calea relativă concatenând primul şi al treilea element din tuplul
curent returnat de walk(); reamintim că primul e calea folderului la care a ajuns walk, iar al
treilea e lista numelor fişierelor (parcursă cu for x in fisiere);
pentru fiecare fişier s-a detectat poziţia ULTIMULUI punct, pentru cazurile în care ar putea exista
mai multe puncte (rfind găseşte ultima apariţie a caracterului dorit, find o găseşte pe prima);
noua cale a fişiereului s-a creat din calea veche, din care s-a decupat extensia cu x[0:pozitie+1]
(numele fişierului până la punct inclusiv) şi s-a adăugat noua extensie (csv);
apoi s-a apelat rename pentru înlocuirea căii, care are ca efect schimbarea numelui fişierului.
Se poate verifica pe disc rezultatul operaţiei.
Într-o manieră similară se pot realiza orice transformări asupra folderelor şi fişierelor returnate
de walk, inclusiv ştergeri. În cazul ştergerilor, parcurgerea trebuie să fie bottom-up, deoarece trebuie
golit fiecare folder înainte de ştergerea sa.
Aceste exemple funcţionează doar pe Windows, deoarece concatenarea între cale şi numele
fişierelor sau folderelor s-a făcut prin \\, acesta fiind separatorul acceptat de Python pt Windows.
Deoarece separatorul diferă de la un sistem de operare la altul, pentru ca programele să fie portabile,
căile trebuie construite prin intermediul modulului os.path ce asigură conversia automată a sintaxei
căilor după sistemul de operare.
>>> os.path.join('aaa','bbb')
'aaa\\bbb'
- asigură o concatenare pornind de la premisa că argumentele sunt componente ale unei căi;
funcţia oferă garanţia folosirii separatorului corect indiferent de sistemul de operare
>>> os.path.getsize('folder1')
0L
- indică dimensiunea folderului sau fişierului; 0L indică faptul că e gol; acesta e un test important
pentru a evita erorile la ştergerea de foldere
29 Lucrarea 2. Programarea în limbajul Python - lucrul cu fișiere și directoare
2.5 Bibliografie
D. M. Beazley, Python Essential Reference, Pearson Education, 2009
J. M. Zelle, Python programming: an introduction to computer science, Ed. Wilsonville: Franklin, Beedle,
2004
M.Lutz, Programming Python,O'Reilly, 2011.