Domyślnie pliki otwierane są w trybie tekstowym, co pozwala zapisać i odczytać dane w określonym kodowaniu jako stringi. Współcześnie, najczęściej używanym kodowaniem dla tekstu jest standard UTF-8. Trzeba jednak pamiętać, że w trybie tekstowym znaki końca linii dla systemów Unix (\n) i Windows (\r\n) różnią się, aczkolwiek przy odczycie tekstowym plików następuje automatyczna konwersja tych znaków na \n, to przy próbie potraktowania w ten sposób plików z binarnie zapisanymi wartościami nastąpi duże prawdopodobieństwo uszkodzenia i zniekształcenia danych binarnych. W przypadku plików binarnych niemożliwe jest także określenie ich kodowania.

Próba korzystania z plików z zapisem do nich danych napotyka podstawowy problem związany z faktem, iż dane w pliku tekstowym to ciągi znakowe, zatem wszystkie dane innego typu w naszym programie muszą być przekształcane do postaci znakowej, a w drugą stronę konwertowane z tej postaci do właściwego typu danych. W przypadku zagnieżdżających się struktur danych ręczne parsowanie ich staje się skomplikowane i niewygodne, prowadząc najczęściej do błędów.

JSON

Jednym ze sposobów obsługi danych nie będących stringami jest ich serializacja1pobieranie hierarchii danych i automatyczne konwertowanie ich na ciągi liczbowe z wykorzystaniem odpowiednich modułów standardowych. Jednym z nich jest np. json, czyli JavaScript Object Notation. Proces odwrotny, polegający na odczycie danych z pliku we właściwym formacie i przywrócenie ich struktury nazywa się deserializacją.

Przykład stworzenia pliku, zapisania i odczytania używanej złożonej struktury danych, jest zamieszczony poniżej:

import json

Dane = (("Anna","Kowalska",1998),("Bartosz","Magłowski",2003))
with open("Dane.json","w", encoding="utf-8") as f:
    json.dump(Dane,f)
    f.close()

with open("Dane.json","r", encoding="utf-8") as f:
    odczyDane=json.load(f)
    for dane in odczyDane:
        print("Osoba {0} {1} urodziła się w {2} roku.".format(*dane))

    f.close()

Jak widać udało nam się stworzyć plik, zapisać do niego dane tekstowe i numeryczne; a następnie przywrócić z pliku te dane dla późniejszej ich obróbki.

Zawartość pliku z powyższego przykładu:


[["Anna", "Kowalska", 1998], ["Bartosz", "Mag\u0142owski", 2003]]

Czy aby wszystko jest ok??

import json

Dane = (("Anna","Kowalska",1998),("Bartosz","Magłowski",2003))
with open("Dane.json","w", encoding="utf-8") as f:
    json.dump(Dane,f)
    f.close()

with open("Dane.json","r", encoding="utf-8") as f:
    odczyDane=json.load(f)
    for dane in odczyDane:
        print("Osoba {0} {1} urodziła się w {2} roku.".format(*dane))
        print("Typ zmiennej pierwszej to: ", type(dane[0]).__name__)
        print("Typ zmiennej drugiej to:   ", type(dane[1]).__name__)
        print("Typ zmiennej trzeciej to:  ", type(dane[2]).__name__)
        print("Rok urodzenia osoby to: {0}, a pożądany typ tej danej to {1} ".format(int(dane[2]),type(int(dane[2])).__name__))
    f.close()

Czy zatem serializacja z wykorzystaniem json zabezpiecza nam właściwe typy danych?

Tak, chociaż brak w pliku informacji o typie danych, to Python w sposób utajony dokonał analizy pobieranych danych przypisując je do odtwarzanej struktury, mniej więcej w ten sam sposób w jaki ocenia typ w momencie powoływania do życia i inicjalizowania wartością nowej zmiennej

W efekcie widać zatem, że z naszymi danymi wszystko jest OK.

Zatem spróbujmy napisać program z wykorzystaniem nowo zdobytej wiedzy.

Zadanie 1: Pełnoletność

Napisz program, który po uruchomieniu odczytuje (uprzednio stworzony plik osoby.json z danymi 10 osób, a następnie wyświetla ich Imiona, Nazwiska i wiek każdej z nich, sprawdzając czy jest ona już pełnoletnia, jeśli tak to pisząc na końcu linii znak P, jeśli nie to N.

Co kiszenie (pickle) ogórków ma do plików?

Powyższy przykład modułu z wykorzystaniem standardu JSON pokazuje, że możliwe jest zrzucenie do pliku wartości liczbowych, a następnie ich przywrócenie. Dane przechowywane są w trybie tekstowym, który absolutnie nie jest metodą bezpieczną, ani też nie jest metodą optymalną pod względem zajętości pamięci dyskowej i rozmiaru takiego pliku. Inną metodą jest skorzystanie z modułu pickle potrafiącego “konserwować” nasze dane 2konserwacja: preservation – to owe pickling: kiszenie danych i dokonywać ich zrzutu do pliku binarnego, oraz odtworzenie ich przy odczycie.

Można zatem rozważyć w jaki sposób to zrobić analizując program poniżej:

import pickle

with open("Data.dat", "wb") as plik:
    d=20
    pickle.dump(d, plik)
    d=11
    pickle.dump(d, plik)
    d=2024
    pickle.dump(d, plik)
    plik.close()

with open("Data.dat", "rb") as plik:
    try:
        while True:
            d=pickle.load(plik)
            print(d)
    except EOFError: print("Skończyłem czytać zbiór...")
    plik.close()

Można teraz spróbować otworzyć podgląd tak stworzonego pliku, aby zapoznać się z jego strukturą. Jak widać, struktura ta nie jest zbyt czytelna.

Porównując ten sposób z poprzednim programem uzyskujemy:

import pickle

Dane = (("Anna","Kowalska",int(1998)),("Bartosz","Magłowski",2003))

###zapis obiektu do pliku
with open("Data.dat", "wb") as plik:
    pickle.dump(Dane, plik)

###Odczyt z pliku
with open("Data.dat", "rb") as plik:
    try:
        while True:
            odczytaneDane=pickle.load(plik)
    except EOFError: print("Skończyłem czytać zbiór...")
    plik.close()
for d in odczytaneDane:
    print("Osoba {0} {1} urodziła się w {2} roku.".format(*d))

Zadanie 2: Pełnoletność i świadomość

Przeredaguj poprzedni program, z wykorzystaniem modułu pickle. Zastanów się nad pros&cons (zaletami i wadami) takiego rozwiązania. Sprawdź wielkość plików danych w obu przypadkach.

Zadanie 2′:

Zwiększ liczbę składowych struktury danych do:
– Identyfikator osoby w standardzie: xxxx-xxxx (jako liczby)
– Imię,
– Nazwisko,
– Data urodzenia RRRR-MM-DD (jako liczby, nie jako string)
– numer telefonu
Zwiększ liczbę elementów takiej “bazy danych” do 100…

Porównaj wielkości plików w pierwszym i drugim sposobie zapisu.

Wyniki rozważań opisz w sprawozdaniu i wgraj je jako plik .pdf (wraz z plikami będącymi listingami programów .py) do Moodle.

Spytaj prowadzącego o hasło
To view this protected content, enter the password below: