Komunikacja człowiek - komputer

Post on 13-Jan-2016

43 views 0 download

description

Komunikacja człowiek - komputer. Wykład 3. Pliki i bazy danych w Pythonie. Literatura: Jakub Swacha – kurs Pythona http://uoo.univ.szczecin.pl/~jakubs/ Marcin Młotkowski – kurs języka Python http://www.ii.uni.wroc.pl/~marcinm/dyd/python/ - PowerPoint PPT Presentation

Transcript of Komunikacja człowiek - komputer

Komunikacja człowiek - komputer

1

Wykład 3Pliki i bazy danych w Pythonie

Opracował:dr inż. Wojciech Bienieckiwbieniec@kis.p.lodz.plhttp://wbieniec.kis.p.lodz.plKatedra Informatyki StosowanejPolitechnika Łódzka

Literatura:

Jakub Swacha – kurs Pythonahttp://uoo.univ.szczecin.pl/~jakubs/

Marcin Młotkowski – kurs języka Pythonhttp://www.ii.uni.wroc.pl/~marcinm/dyd/python/

Python 2.6.4 documentationhttp://docs.python.org/

2

Atrybuty:'r' – do odczytu'w' – do zapisu'a' – do ‘appendu’'r+' – do odczytu i zapisu'rb', 'wb', 'ab' – odczyt i zapis binarny

f.close() – zamyka plik

Otwarcie i zamknięcie pliku:f = open('plik', 'r')

Otwieranie plików

Atrybuty obiektu plikowego

3

closed określa czy plik jest zamknięty >>> f1.closedfalse

Obiekty plikowe mają trzy podstawowe atrybuty:

name zawiera nazwę pliku (tak jak podano ją przy otwarciu) >>> f1.name'plik1.txt'mode określa tryb, w jakim otwarto plik  >>> f1.mode'w'

Błędy i wyjątki – otwarcie nieistniejącego pliku

4

>>> try:... fsock = open("c:/niemapliku.txt") ... except IOError: ... print "Plik nie istnieje" ... print "Ta linia zawsze zostanie wypisana"Plik nie istnieje Ta linia zawsze zostanie wypisana

>>> f = open("plik", "r")Traceback (most recent call last): File "<stdin>", line 1, in ? IOError: [Errno 2] No such file or directory: 'plik'

Plik nie istnieje i dlatego zostanie rzucony wyjątek IOError. Ponieważ nie przechwytujemy tego wyjątku, Python po prostu wypisuje błąd i zakańcza działanie programu.

Czytanie pliku tekstowego

5

f.readlines() – zwraca listę wierszy

f.read() – odczyt całego pliku

f.read(l_zn) – odczyt tylko l_zn znaków. Zwracany jest string

f.readline() – odczytuje jeden wiersz. Zwracamy razem ze znakiem "\n"

Obsługa błędów czytania

6

try:f = open(filename, "rb", 0)try:

f.seek(-128, 2)tagdata = f.read(128)

finally:f.close()

except IOError:pass

IOError może być rzucony przez:- open (plik może nie istnieć), - seek (plik może być mniejszy niż 128 bajtów)- read (być może dysk posiada uszkodzony sektor)

kod z bloku finally zostanie zawsze wykonany, nawet jeśli jakaś instrukcja bloku try rzuci wyjątek. Pass jest wyrażeniem Pythona, które nic nie robi.

Przykłady czytania pliku

7

f = open('test.py', 'r')while True:

wiersz = f.readline()if len(wiersz) == 0: breakprint wiersz,

f.close()

f = open('test.py', 'r')for wiersz in f:print wiersz,

words = open("c:/730.txt").read().split()print words[:30]print words.count("Oliver")print words.count("Twist")print len(set(words))

8

f = open("Feel.mp3","rb")print f.tell() f.seek(-128, 2)print f.tell() tagData = f.read(128) print tagDataprint f.tell()

read czyta określoną liczbę bajtów z otwartego pliku i zwraca dane w postaci łańcucha znaków, które zostały odczytane. Opcjonalny argument określa maksymalną liczbę bajtów do odczytu. Jeśli nie zostanie podany argument, read będzie czytał do końca pliku.

tell zwraca aktualną pozycję w otwartym pliku.

seek służy do poruszania się po otwartym pliku. Drugi argument: 0 – pozycja bezwzgledna, 1 – względem pozycji aktualnej 2 – względem końca

Przykład: czytanie TAG z MP3

Zapis do pliku

9

Plik musi być otwarty w trybie do zapisu lub odczytu i zapisu 'w', 'a', 'r+'

f.write(string) zapisuje zawartość łańcucha string ale nic nie zwraca

>>> f.write('This is a test\n')

Aby zapisać dane innego typu muszą być skonwertowane na string

value = ('the answer', 42) s = str(value)f.write(s)

f = ('/tmp/workfile', 'r+') f.write('0123456789abcdef')f.seek(5)print f.read(1) #wypisze 5f.seek(-3, 2) #3 bajt przed końcemf.read(1) #wypisze d

10

n=raw_input("Podaj pełną nazwę pliku do skopiowania>") oryg = file(n,"rb")                    kop = file("kopia "+n,"wb")# otwieramy kopię do zapisuwhile True:                     b = oryg.read(1)     # wczytujemy 1 bajt z oryginału      if not b: break      # Koniec pliku!      kop.write(b)         kop.close()                oryg.close()              print "Kopiowanie zakończone pomyślnie"

Kopiowanie pliku

11

t=raw_input("Podaj pełną nazwę pliku >")p=input("Podaj przesunięcie >”)f1 = open(t,"r+b") s=f1.read()        sz=""                   # sz oznacza tekst zaszyfrowanyfor c in s:                a=ord(c)            # wyliczamy kod ASCII    if a > 32:          # znaków białych i sterujących nie szyfrujemy        c=chr((a+p) % 256)   # inne przesuwamy     sz+=c               # dodajemy do szf1.seek(0)               # ustawiamy pozycję pliku na jego początkuf1.write(sz)            # zapisujmy szf1.close()              # zamykamy plik

Kodowanie pliku

Zapisywanie całych wierszy

12

lista = ["napis1", "napis 2", "napis 3"]g=open("test.txt","w")g.writelines(lista) #zapisuje do pliku listę, oddziela znakiem " "g.close()

f.writelines(['to\n', 'są\n', 'kolejne\n', 'wiersze\n'])

13

Pliki i struktury: MP3 TAG

Obsługa pliku *.ini

14

Obsługa pliku *.ini

15

import ConfigParserimport sysconfig = ConfigParser.ConfigParser() config.add_section("book") config.set("book", "title", "the python standard library") config.set("book", "author", "fredrik lundh") config.add_section("ematter")config.set("ematter", "pages", 250) config.write(sys.stdout)

[book]title = the python standard libraryauthor = fredrik lundh[ematter]pages = 250

Obsługa pliku *.ini – zmiany

16

Usuwanie:ini.remove_option('window', 'height')ini.remove_section('window')

Modyfikacja parametrów:ini.set('window', 'height', 100)

Zapis konfiguracjif = open('konfig.ini', 'w')ini.write(f)fh.close()

Obsługa plików CSV

17

CSV – Comma Separated Values

Dane"Anna", "Kowalska", 2000-01-01, 3"Jan", "Nowak", 2006-04-01, 2Notowania giełdowe2006-04-26;1415.79;183.29;102.14;2006-04-25;1415.88;183.43;102.31;Parametry formatu:

delimiter – separator, np. ',' ';' ':‘lineterminator – koniec wierszaquotechar – znak cudzysłowuquoting – kiedy ujmować pola w cudzysłów:QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE

Odczyt i zapis pliku CSV

18

import csvreader = csv.reader(open('/etc/passwd', 'r'), delimiter=':', quoting=csv.QUOTE_NONE)for row in reader:print row

import csvdata = [ [1, 'Kubus'], [2, 'Puchatek'] ]writer = csv.writer( open('out', "w"), dialect=csv.excel)writer.writerows(data)

CSV - Wykorzystanie słowników

19

fh = open('notowania.csv', "r")reader = csv.DictReader(fh, delimiter=';')for row in reader: for k in row.keys(): print k, row[k]

fh = open('notowania.csv', "r")klucze = ['lp', 'name']reader = csv.DictReader(fh, fieldnames= klucze)for row in reader: print row['lp'], row['name']

Własne klucze:

20

Rekord Rekord Rekord Rekord Rekord Rekord

Indeks(int) Imię (char[20] Nazwisko (char[30]) Ocena (float) Semestr(byte) Grupa(char[5])

Rekord

Plik

Pliki rekordowe

21

f=open("studenci","wb")

imie="Jan"

nazwisko="Kowalski"

indeks=70678

ocena=4.5

semestr=3

grupa="3D20"

import struct

rekord=struct.pack("<L20s30sfb5s",indeks,imie,nazwisko,ocena,semest

r,grupa)

f.write(rekord)

f.close()

Plik rekordowy – użycie struct

Struct – znaczenie symboli

22

Format Typ języka C Python

x pad byte brak wartości

c char napis o długości 1

b signed char integer

B unsigned char integer

h short integer

H unsigned short integer

i int integerI unsigned int longl long integer

L unsigned long long

q long long long

Q unsigned long long long

f float floatd double floats char[] stringp char[] stringP void * integer

Znaczenie pierwszego znaku

23

Znak Porządek bajtów Rozmiari wyrównanie

@ odpowiedni dla maszyny

odpowiedni dla maszyny

= odpowiedni dla maszyny standardowy

< little-endian standardowy

> big-endian standardowy

! sieciowy (= big-endian) standardowy

Jeśli pierwszym znakiem napisu nie jest żaden z powyższych, przyjmuje się interpretację odpowiadającą znakowi "@". Porządkiem bajtów odpowiednim dla maszyny może być zarówno big-endian jak i little-endian, w zależności od systemu, na którym wykonywany jest program. Przykładowo, procesory firm Motorola oraz Sun używają porządku bajtów big-endian; procesory firm Intel oraz DEC używają little-endian.

Odczyt pliku rekordowego

24

g=open("studenci","rb")

sr=struct.calcsize("<L20s30sfb5s")

while True:

rek = g.read(sr)

if not rek: break

indeks,imie,nazwisko,ocena,semestr,grupa=\

struct.unpack("<L20s30sfb5s",rek)

print indeks,imie,nazwisko,ocena,semestr,grupa

g.close()

25

Serializacja obiektu polega na przekształceniu danych go opisujących w ciąg bajtów (funkcja dumps), z którego można później odtworzyć taki sam obiekt (funkcja loads).

Serializacja obiektów

Serializacja własnych obiektów

26

class wymiary3:

      x=0; y=0; z=0    

w3=wymiary3()

w3.x=1; w3.y=2; w3.z=3

zapis=pickle.dumps(w3)

del w3

w3=pickle.loads(zapis)

print w3.x; w3.y; w3.z

Dzięki pickle można serializować obiekty należące do klas zdefiniowanych przez nas.

Zapis bezpośrednio do pliku

27

f1=file("trzy_rzeczy.txt","w+")pickle.dump((lista,slownik,w3),f1)lista=[]; slownik={}; w3=wymiary3()print lista; slownik; w3.x

[]{}0

f1.seek(0)(lista,slownik,w3)=pickle.load(f1)print lista; slownik; w3.x

[1, 2, 'trzy', 4]{'a': 'b', 1: 2}1

Moduł dumbdbm

28

Moduł tworzy słownik zapisany na dysku. Składa się on z dwóch plików „.dat” i indeksującego „.dir”). Obsługa bazy jest identyczna jak obsługa słownika, z tą różnicą, że wszystkie zachowane w niej dane przechowywane są nie w pamięci, lecz na dysku.

import dumbdbm

db=dumbdbm.open("prosta_baza")

db['napis']="hej ho!"

print db['napis']

db.close()

Bazy danych typu dbm pozwalają używać napisów jako kluczy i wartości. Próba zachowania w niej obiektu innego niż napis typu, nieuchronnie kończy się błędem

Moduł shelve

29

analogiczny sposób dostępu do danych (podobny słownikowi), umożliwiając jednak zachowywanie obiektów dowolnego typu (nie tylko napisów)

import shelve

lista = [1, 2, "trzy", 4]

slownik={"a":"b",1:2}

db = shelve.open ('baza')

db['lista']=lista

db['slownik']=slownik

Moduł shelve - możliwości

30

liczba elementów:>>> len(db)2

Sprawdzenie istnienia klucza:>>> 'lista' in dbTrue

Lista kluczy:>>> db.keys()['lista', 'slownik']

Moduł shelve - możliwości

31

Wyszukanie wartości po kluczu>>> db['lista'][1, 2, 'trzy', 4]>>> db['slownik']{'a': 'b', 1: 2}

Lista wartości:>>> db.values()[[1, 2, 'trzy', 4], {'a': 'b', 1: 2}]

Lista elementów:>>> db.items()[('lista', [1, 2, 'trzy', 4]), ('slownik', {'a': 'b', 1: 2})]

Moduł shelve - możliwości

32

Modyfikacja wartości:>>> db['lista']=[3,2]

Usunięcie elementu:>>> del db['lista']>>> db.items()[('slownik', {'a': 'b', 1: 2})]

Usunięcie wszystkich elementów:>>> db.clear()>>> db.items()[]

Zamknięcie bazy>>> db.close()

Baza danych SQLite

33

Możliwe jest tworzenie wstępnej wersji aplikacji z wykorzystaniem SQLite, a następnie przeniesienie jej na standardowy serwer bazy danych (PostgreSQL czy Oracle)

SQLite to biblioteka napisana w języku C

Obsługuje "lekką" bazę danych w postaci jednego pliku na dysku.

Nie wymaga instalacji serwera ani łączenia się z serwerem.

Używa odmiany języka SQL

Może być używana jako struktura danych skojarzona z aplikacją

Implementuje DB API 2.0 z rozszerzeniami

Proste operacje na bazie

34

import sqlite3

db = sqlite3.connect('temp.db')

kursor = db.cursor()

kursor.execute("create table Student(nazwisko text, imie text, indeks int,

ocena real)")

db.commit()kursor.execute("insert into Student values('Kowalski' , 'Jan' , 70660, 4.5)")

kursor.execute('SELECT * FROM Student')

for row in kursor:

print row

kursor.close()

Zapytanie sparametryzowane

35

# NIE! – niebezpieczne nazwisko = 'Kowalski' kursor.execute("select * from Student where nazwisko = '%s' " % nazwisko)

Czasem zapytanie będzie wykorzystywać zmienne z programu. Sklejanie zapytania poprzez użycie operacji na stringach w Pythonie może być niebezpieczne (narażenie na atak Injection).W zamian należy użyć symbol zastępczy.

# TAK! t = (nazwisko,) kursor.execute('select * from Student where nazwisko=?', t)

# Bardziej złożony przykładfor t in [('Kowalski', 'Jan', 70123, 4.5), ('Wisniewski', 'Maciej', 143245, 3.5), ('Nowak', 'Grzegorz', 132322, 3), ]: kursor.execute('insert into Studencivalues (?,?,?,?)', t)

SQLite w pamięci i generatory

36

import sqlite3

def char_generator():

import string

for c in string.letters[:26]:

yield (c,)

con = sqlite3.connect(":memory:")

cur = con.cursor()

cur.execute("create table characters(c)")

cur.executemany("insert into characters(c) values (?)", char_generator())

cur.execute("select c from characters")

print cur.fetchall()

„Prawdziwe” bazy danych

37

Python obsługuje różne serwery relacyjnych baz danych między innymi:OracleDB/2MySQLPostgreSQLMS SQL

Python Database API SpecificationZunifikowany interfejs (metody i pola) dostępu do różnych silników relacyjnych baz danych (Aktualna wersja: 2.0)

Korzystanie z MySQL

38

import MySQLdb

db = MySQLdb.connect(host='localhost', db='studenci', user='root',

passwd='root')wynik = db.cursor()

wynik.execute('SELECT * FROM Student')

row = wynik.fetchone()

while row:

print row

row = wynik.fetchone()

wynik.close()

db.close()