SlideShare une entreprise Scribd logo
1  sur  174
Télécharger pour lire hors ligne
.
              Python
          Zaawansowane IO
    przetwarzanie tekstu, input, output
.

             Robert Zaremba

                  Scale it


        Wrocław 2011 listopad 10




                              .    .      .   .   .   .
Table of Contents

1.   Wstęp

2.   Python 3

3.   Tekst

4.   Formatowanie tesktu

5.   Dane binarne

6.   Moduł I/O

7.   System Interface

8.   Projektowanie bibliotek

                                                          .   .         .      .       .     .

     Robert Zaremba (Scale it)   Python Zaawansowane IO           Wrocław 2011 listopad 10   2 / 91
Po co tekst i I/O



    Większość programów komunikują się ze światem za pomocą
    czytelnego tekstu.




                                                       .   .         .      .       .     .

  Robert Zaremba (Scale it)   Python Zaawansowane IO           Wrocław 2011 listopad 10   3 / 91
Po co tekst i I/O



    Większość programów komunikują się ze światem za pomocą
    czytelnego tekstu.
            odczytują i zapisują tekst z pliku
            odczytują i zapisują tekst do bazy danych
            odbierają i wysyłają po tekst po sieci.




                                                          .   .         .      .       .     .

  Robert Zaremba (Scale it)      Python Zaawansowane IO           Wrocław 2011 listopad 10   3 / 91
Po co tekst i I/O



    Większość programów komunikują się ze światem za pomocą
    czytelnego tekstu.
            odczytują i zapisują tekst z pliku
            odczytują i zapisują tekst do bazy danych
            odbierają i wysyłają po tekst po sieci.
    I/O jest “corem” tego do czego używamy Pythona (skrypty,
    przetwarzanie danych, sklejanie programów ...)




                                                          .   .         .      .       .     .

  Robert Zaremba (Scale it)      Python Zaawansowane IO           Wrocław 2011 listopad 10   3 / 91
Po co tekst i I/O



    Większość programów komunikują się ze światem za pomocą
    czytelnego tekstu.
            odczytują i zapisują tekst z pliku
            odczytują i zapisują tekst do bazy danych
            odbierają i wysyłają po tekst po sieci.
    I/O jest “corem” tego do czego używamy Pythona (skrypty,
    przetwarzanie danych, sklejanie programów ...)
Co się pojawiło? Python 3




                                                          .   .         .      .       .     .

  Robert Zaremba (Scale it)      Python Zaawansowane IO           Wrocław 2011 listopad 10   3 / 91
Python 3




    W Python 3 na nowo zaimplementowano biblioteki powiązane z I/O.




                                                       .   .         .      .       .     .

  Robert Zaremba (Scale it)   Python Zaawansowane IO           Wrocław 2011 listopad 10   4 / 91
Python 3




    W Python 3 na nowo zaimplementowano biblioteki powiązane z I/O.
    Mamy nowe typy danych




                                                       .   .         .      .       .     .

  Robert Zaremba (Scale it)   Python Zaawansowane IO           Wrocław 2011 listopad 10   4 / 91
Python 3




    W Python 3 na nowo zaimplementowano biblioteki powiązane z I/O.
    Mamy nowe typy danych
    Python 3 dostarcza wprowadza w ogóle dużo zmian (nowe biblioteki,
    część starych bibliotek pod nowymi nazwami - eg urllib …)
Większość starego kodu (z Pythona 2) da się przenieść do Pythona 3 za
pomocą narzędzia 2to3




                                                       .   .         .      .       .     .

  Robert Zaremba (Scale it)   Python Zaawansowane IO           Wrocław 2011 listopad 10   4 / 91
Python 3




    W Python 3 na nowo zaimplementowano biblioteki powiązane z I/O.
    Mamy nowe typy danych
    Python 3 dostarcza wprowadza w ogóle dużo zmian (nowe biblioteki,
    część starych bibliotek pod nowymi nazwami - eg urllib …)
Większość starego kodu (z Pythona 2) da się przenieść do Pythona 3 za
pomocą narzędzia 2to3
Ale nie operacje I/O




                                                       .   .         .      .       .     .

  Robert Zaremba (Scale it)   Python Zaawansowane IO           Wrocław 2011 listopad 10   4 / 91
Pojęcia




    str vs unicode




                                                       .   .         .      .       .     .

  Robert Zaremba (Scale it)   Python Zaawansowane IO           Wrocław 2011 listopad 10   5 / 91
Pojęcia




    str vs unicode
    print statement (i domyślne użycie __str__() metody call)




                                                       .   .         .      .       .     .

  Robert Zaremba (Scale it)   Python Zaawansowane IO           Wrocław 2011 listopad 10   5 / 91
Pojęcia




    str vs unicode
    print statement (i domyślne użycie __str__() metody call)
    metody dostępu do plików




                                                       .   .         .      .       .     .

  Robert Zaremba (Scale it)   Python Zaawansowane IO           Wrocław 2011 listopad 10   5 / 91
Pojęcia




    str vs unicode
    print statement (i domyślne użycie __str__() metody call)
    metody dostępu do plików
    std




                                                       .   .         .      .       .     .

  Robert Zaremba (Scale it)   Python Zaawansowane IO           Wrocław 2011 listopad 10   5 / 91
Table of Contents

1.   Wstęp

2.   Python 3

3.   Tekst

4.   Formatowanie tesktu

5.   Dane binarne

6.   Moduł I/O

7.   System Interface

8.   Projektowanie bibliotek

                                                          .   .         .      .       .     .

     Robert Zaremba (Scale it)   Python Zaawansowane IO           Wrocław 2011 listopad 10   6 / 91
Python 3
składnia




      print




                                                         .   .         .      .       .     .

    Robert Zaremba (Scale it)   Python Zaawansowane IO           Wrocław 2011 listopad 10   7 / 91
Python 3
składnia




      print
      wyjątki:
             try:
                 ...
             except Exception as e:     # "as" wymagane
                 ...




                                                          .   .         .      .       .     .

    Robert Zaremba (Scale it)    Python Zaawansowane IO           Wrocław 2011 listopad 10   7 / 91
Python 3
built-ins




       zmieniono wiele wbudowanych operatorów
       range tworzą teraz generator, a nie listy
       wiele kolekcji zwracają iteratory zamiast list
       ogólnie Python 3 preferuje iteratory / generatory




                                                          .   .         .      .       .     .

    Robert Zaremba (Scale it)    Python Zaawansowane IO           Wrocław 2011 listopad 10   8 / 91
Python 3
Porządek w bibliotece


      Python2:
             urllib, urllib2 - dwie biblioteki? gdzie co jest i po co?
                     from urllib2 import urlopen
                     u = urlopen("http://www.example.com")

             Queue, SocketServer
             anydbm, dbhash, dbm, dumbdbm, gdbm ...
      Python3
             urllib - jedna biblioteka z poukładaną funkcjonalnością
                     from urllib.request import urlopen
                     u = urlopen("http://www.example.com")

             queue, socketserver
             dbm.{anydbm, dbhash, dbm, dumbdbm, gdbm ...}

                                                            .   .         .      .       .     .

   Robert Zaremba (Scale it)       Python Zaawansowane IO           Wrocław 2011 listopad 10   9 / 91
Python 3
2to3



Przykładowy kod dla Python2.7
       # printlinks.py
       import urllib
       import sys
       from HTMLParser import HTMLParser

       class LinkPrinter(HTMLParser):
         def handle_starttag(self,tag,attrs):
           if tag == 'a':
             for name,value in attrs:
               if name == 'href': print value

       data = urllib.urlopen(sys.argv[1]).read()
       LinkPrinter().feed(data)



                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   10 / 91
Python 3
2to3



użycie narzędzia 2to3.
Pokazuje co i jak zamienić
       bash % 2to3 printlinks.py
       ...
       --- printlinks.py (original)
       +++ printlinks.py (refactored)
       @@ -1,12 +1,12 @@
       -import urllib
       +import urllib.request, urllib.parse, urllib.error
       -from HTMLParser import HTMLParser
       +from html.parser import HTMLParser
       -if name == 'href': print value
       +if name == 'href': print(value)




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   11 / 91
Python 3
2to3



użycie narzędzia 2to3.
Pokazuje co i jak zamienić
       bash % 2to3 printlinks.py
       ...
       --- printlinks.py (original)
       +++ printlinks.py (refactored)
       @@ -1,12 +1,12 @@
       -import urllib
       +import urllib.request, urllib.parse, urllib.error
       -from HTMLParser import HTMLParser
       +from html.parser import HTMLParser
       -if name == 'href': print value
       +if name == 'href': print(value)

Ale dalej nie działa, czemu?

                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   11 / 91
Python 3
2to3



       bash % python3 printlinks.py http://www.python.org
       Traceback (most recent call last):
         File "printlinks.py", line 12, in <module>
           LinkPrinter().feed(data)
         File "/Users/beazley/Software/lib/python3.1/html/parser.py",
       line 107, in feed
           self.rawdata = self.rawdata + data
       TypeError: Can't␣convert␣'bytes'␣object␣to␣str␣implicitly

Jak widzimy błąd jest w obsłudze napisów.
2to3 nie może zgadnąć o jakie napisy nam chodzi




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   12 / 91
Python 3
2to3



       bash % python3 printlinks.py http://www.python.org
       Traceback (most recent call last):
         File "printlinks.py", line 12, in <module>
           LinkPrinter().feed(data)
         File "/Users/beazley/Software/lib/python3.1/html/parser.py",
       line 107, in feed
           self.rawdata = self.rawdata + data
       TypeError: Can't␣convert␣'bytes'␣object␣to␣str␣implicitly

Jak widzimy błąd jest w obsłudze napisów.
2to3 nie może zgadnąć o jakie napisy nam chodzi
Fix:
        LinkPrinter().feed(data.decode(′ utf − 8′ ))



                                                          .   .      .      .       .    .

   Robert Zaremba (Scale it)     Python Zaawansowane IO       Wrocław 2011 listopad 10   12 / 91
Python 3
I/O




Po co to wszytko?

                     Wiele “prawdziwych” programów polegają na I/O




                                                             .   .      .      .       .    .

      Robert Zaremba (Scale it)     Python Zaawansowane IO       Wrocław 2011 listopad 10   13 / 91
Table of Contents

1.   Wstęp

2.   Python 3

3.   Tekst

4.   Formatowanie tesktu

5.   Dane binarne

6.   Moduł I/O

7.   System Interface

8.   Projektowanie bibliotek

                                                          .   .      .      .       .    .

     Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   14 / 91
Tekst
Problemy




     kodowanie - koszmar
     Zależności między bibliotekami
     biblioteki operują na stringach
     trzeba konfigurować klasy aby wiedziały jak stringi są kodowane
     znak → ile bajtów go koduje?
     tłumaczenie tekstów
     niektóre biblioteki nie obsługują wielu kodowań automatycznie
     trzeba samemu przekodowywać tekst
     wczytywanie plików.



                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   15 / 91
Tekst
Problemy




     kodowanie - koszmar
     Zależności między bibliotekami
     biblioteki operują na stringach
     trzeba konfigurować klasy aby wiedziały jak stringi są kodowane
     znak → ile bajtów go koduje?
     tłumaczenie tekstów
     niektóre biblioteki nie obsługują wielu kodowań automatycznie
     trzeba samemu przekodowywać tekst
     wczytywanie plików.
Python ma być w prosty i intuicyjny

                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   15 / 91
Tekst
co poukładano




     W Python 3 tekst jest unicode
     przetwarzanie tekstu także odbywa się na podstawie unicode




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   16 / 91
Tekst
Unicode




     każdy znak ma swój unikalny kod (w lokalne kodowania są
     przystosowane do lokalnych alfabetów)




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   17 / 91
Tekst
Unicode




     każdy znak ma swój unikalny kod (w lokalne kodowania są
     przystosowane do lokalnych alfabetów)
     większa “pojemność znaku”
     tekst więcej zajmuje :(




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   17 / 91
Tekst
Unicode




     każdy znak ma swój unikalny kod (w lokalne kodowania są
     przystosowane do lokalnych alfabetów)
     większa “pojemność znaku”
     tekst więcej zajmuje :( )
     największy numer znaku: U+10FFF
     http://www.unicode.org/charts




                                                          .   .      .      .       .    .

   Robert Zaremba (Scale it)     Python Zaawansowane IO       Wrocław 2011 listopad 10   17 / 91
Tekst
Unicode




     każdy znak ma swój unikalny kod (w lokalne kodowania są
     przystosowane do lokalnych alfabetów)
     większa “pojemność znaku”
     tekst więcej zajmuje :( )
     największy numer znaku: U+10FFF
     http://www.unicode.org/charts
     unicode literals:
              "xf1"           # standard ascii 'ñ'
              "u2191":        # ↑
              "U0001d122"




                                                            .   .      .      .       .    .

   Robert Zaremba (Scale it)       Python Zaawansowane IO       Wrocław 2011 listopad 10   17 / 91
Tekst
testy z konsolą




testowanie znaków w python2 i python3
methody repr, ascii, chr
         ascii('ś')             # nowa metoda w python3
         repr('ś')
         chr(0x15b)




                                                            .   .      .      .       .    .

    Robert Zaremba (Scale it)      Python Zaawansowane IO       Wrocław 2011 listopad 10   18 / 91
Tekst
Unicode




     Unicod jest przechowywany jako “C” int
     sprawdzenie:
            >>> sys.maxunicode
            65535
            # 16-bits
            >>> sys.maxunicode
            1114111
            # 32-bits




                                                          .   .      .      .       .    .

   Robert Zaremba (Scale it)     Python Zaawansowane IO       Wrocław 2011 listopad 10   19 / 91
Tekst
Unicode




     Tekst w Python3 zajmuje 2 lub 4 razy więcej niż w Python2
     z tego powodu operacje na tekście wykonują się dłużej:
     praca z konsolą
            timeit("text[:-1]","text='x'*100000")
            timeit("text.upper()","text='x'*1000")




                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   20 / 91
Tekst
Unicode - zalety



      Bez względu na kodowanie tekstu w pliku, w pythonie dany tekst jest
      zawsze tak samo reprezentowany (jako unicode)
      Biblioteki nie muszą martwić się o kodowanie
      użytkownik nie musi martwić się komunikację z bibliotekami i
      wyświetlanie




                                                         .   .      .      .       .    .

    Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   21 / 91
Tekst
Unicode - zalety



      Bez względu na kodowanie tekstu w pliku, w pythonie dany tekst jest
      zawsze tak samo reprezentowany (jako unicode)
      Biblioteki nie muszą martwić się o kodowanie
      użytkownik nie musi martwić się komunikację z bibliotekami i
      wyświetlanie
      przy czytaniu strumienia od razu musimy zadeklarować kodowanie →
      mniej błędów
      Wbudowana funkcja open() przyjmuje teraz argument encoding z
      domyślną wartością "utf-8"
      w pythonie 2 wszystko to było ukryte, co mogło powodować błędy w
      przyszłości

                                                         .   .      .      .       .    .

    Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   21 / 91
Tekst
Unicode - konsekwencje




     unicode to wewnętrzna struktura pythona
     inne programy mogą jej nie rozumieć
     Aby przesyłać unicode trzeba używać metod encode, decode
            >>> s = "Jalapeño"
            >>> data = s.encode('utf-8')
            >>> data
            b'Jalapexc3xb1o'
            >>> data.decode('utf-8')
            'Jalapeño'




                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   22 / 91
Tekst
Unicode - Python3, podsumowanie




     Python3 używa unicode do reprezentacji “stringów”
     unicode to inty
     Jeśli nie zaznaczysz inaczej, każdy unicode będzie zakładał kodowanie
     UTF-8
     strumienie bajtów to (bytes)
     bytes nie “zna” kodowań
     bytes to ciągi bajtów
     byets wspiera operacje na ciągach (teracja, slices...)




                                                           .   .      .      .       .    .

   Robert Zaremba (Scale it)      Python Zaawansowane IO       Wrocław 2011 listopad 10   23 / 91
Tekst
Unicode - błędy na jakie można się natrafić



Błąd używania złego kodowania
     >>> f = open('foo',encoding='ascii')
     >>> data = f.read()
     Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
     File "/usr/local/lib/python3.2/encodings/
     ascii.py", line 26, in decode
     return codecs.ascii_decode(input, self.errors)
     [0]
     UnicodeDecodeError: 'ascii' codec can't␣decode␣byte
     0xc3␣in␣position␣6:␣ordinal␣not␣in␣range(128)
     >>>
     >>>␣f␣=␣open('foo',encoding='utf-8')
     >>>␣data␣=␣f.read()



                                                           .   .      .      .       .    .

   Robert Zaremba (Scale it)      Python Zaawansowane IO       Wrocław 2011 listopad 10   24 / 91
Tekst
Uwagi


        unicode to potężny standard. Niektóre znaki są prezentowane jako
        różne kody
            >>> s = "Jalapexf1o"
            >>> t = "Jalapenu0303o"         # 'n' + ' '
            >>> s
            'Jalapeño'
            >>> t
            'Jalapeño'
            >>> s == t
            False
            >>> len(s), len(t)
            (8, 9)

        mimo to tekst powinien być jednoznaczny - jako że kody klawiatury
        są ustandaryzowane.
                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   25 / 91
Table of Contents

1.   Wstęp

2.   Python 3

3.   Tekst

4.   Formatowanie tesktu

5.   Dane binarne

6.   Moduł I/O

7.   System Interface

8.   Projektowanie bibliotek

                                                          .   .      .      .       .    .

     Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   26 / 91
Print
nowe użycie


     definiowanie separatora
            >>> print(1,2,3,sep=':')
            1:2:3
            # python2
            >>> print("Hello","World",sep='')
            HelloWorld

     definiowanie końca linii
            >>> print("What?",end="!?!n")
            What?!?!

     Pytanie: jak w python2 wydrukować coś na ekran bez znaku nowej
     linii na końcu


                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   27 / 91
Print
nowe użycie


     definiowanie separatora
            >>> print(1,2,3,sep=':')
            1:2:3
            # python2
            >>> print("Hello","World",sep='')
            HelloWorld

     definiowanie końca linii
            >>> print("What?",end="!?!n")
            What?!?!

     Pytanie: jak w python2 wydrukować coś na ekran bez znaku nowej
     linii na końcu
            >>> sys.stdout.write()

                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   27 / 91
Formatowanie tekstu




    python2
             s = "%10.2f" % price

    python3
             s = format(price,"10.2f")




                                                         .   .      .      .       .    .

  Robert Zaremba (Scale it)     Python Zaawansowane IO       Wrocław 2011 listopad 10   28 / 91
Formatowanie tekstu
funkcje str, repr, format




      funkcje str, repr, format wywołują odpowiednio metody obiektu:
      __str__, __repr__, __format__




                                                         .   .      .      .       .    .

    Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   29 / 91
Formatowanie tekstu
funkcje str, repr, format




      funkcje str, repr, format wywołują odpowiednio metody obiektu:
      __str__, __repr__, __format__
      format bierze dodatkowy argument - “code formaters”, analogiczny
      do % z python2
             >>> x = 1/3
             >>> format(x,"0.4f")
             '0.3333'
             >>> format(x,"20.2f")
             '␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣0.33'




                                                          .   .      .      .       .    .

    Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   29 / 91
Formatowanie tekstu
code formaters




“code formaters”
”d” - decimal integer
 ”f” - floating point
 ”s” - stringach
”e” - notacja wykładnicza
”x” - hexadecimal
”o” - octal
”b” - binary
”%” - procentowa wartość



                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   30 / 91
Formatowanie tekstu
code formaters




     modyfikatory precyzji i wyrównania:
     [fill][<|>|^][width][thousands sep][.precision]code




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   31 / 91
Formatowanie tekstu
code formaters




     modyfikatory precyzji i wyrównania:
     [fill][<|>|^][width][thousands sep][.precision]code
          [fill] [znak wypełnienia, domyślnie “ ”]
          [<|>|^] [do lewej| do prawej| centruj ]
          [width] [szerokość]
          [thousands sep] [separator tysięcznych części liczby]
          [.precision]code [.ilość cyfr znaczących] typ kodu




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   31 / 91
Formatowanie tekstu
code formaters



        >>> format(1/2., "0.3f")
         '0.500'
        >>> format(1/2., "5.3")
         '␣␣0.5'
        >>> format(1/2., "^5")
         '␣0.5␣'
         >>> format(1/2., "=^5")
         '=0.5='
         >>> format(1e8., ",.0")
         '1+e08'
         >>> format(1e8., ",.0f")
          '100,000,000'
         >>> format(1e8., ",")
         '100,000,000.0'



                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   32 / 91
Formatowanie tekstu
code formaters




metodę __format__(self, fmt) można nadpisać.
Wtedy sami możemy interpretować “code formaters” oraz dodawać swoje
kody.




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   33 / 91
Formatowanie tekstu
string format

Metoda format dla napisów pozwala na tworzenie “koszyków” w tekście.
Koszyki później są zastępowane odpowiednimi wartościami.
Koszyki te mogą zawiertać formatery i argumenty:
    pozycyjne
             "{0}␣has␣{1}␣messages".format("Dave",37)

      pozycyjne
             "{name}␣has␣{n}␣messages".format(name="Dave",n=37)

      pozycyjne
             "{}␣has␣{}␣messages".format("Dave",37)

      indeksowe
             record = {'name' : 'Dave', 'n' : 37}
             '{r[name]}␣has␣{r[n]}␣messages'.format(r=record)
                                                          .   .      .      .       .    .

    Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   34 / 91
Formatowanie tekstu
string format




Jak tworzona jest wartość obiektu który “wkładamy” do koszyka
formatera?
      {item}                    # Replaced by str(item)
      {item!r}                  # Replaced by repr(item)
      {item:fmt}                # Replaced by format(item, fmt)




                                                                  .   .      .      .       .    .

    Robert Zaremba (Scale it)            Python Zaawansowane IO       Wrocław 2011 listopad 10   35 / 91
Formatowanie tekstu
string format




Jak tworzona jest wartość obiektu który “wkładamy” do koszyka
formatera?
      {item}                    # Replaced by str(item)
      {item!r}                  # Replaced by repr(item)
      {item:fmt}                # Replaced by format(item, fmt)

foramt pozwala na pojedyncze zagnieżdżenie {}
      >>> s = ('ACME',50,91.10)
      >>> "{0:{width}s}␣{2:{width}.2f}".format(*s,width=12)
      'ACME␣␣␣␣␣␣␣␣91.10'




                                                                  .   .      .      .       .    .

    Robert Zaremba (Scale it)            Python Zaawansowane IO       Wrocław 2011 listopad 10   35 / 91
Formatowanie tekstu
string format




Jak stworzyć znak ’{’ w formaterze?
     Trzeba użyć ’{{’




                                                         .   .      .      .       .    .

    Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   36 / 91
Formatowanie tekstu
format_map




Metoda format może korzystać z nazwanych argumentów podczas
formatowania tekstu. Jeśli już mamy słownik i nie chcemy nadmiernie
tworzyć ekspansji słownika, możemy skorzystać z metody format_map,
która oczekuje słownika, a nie listy argumentów.
     "{name}␣has␣{n}␣messages".format_map({
         'name': 'Robert'
         'n':     'Hello'
     })




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   37 / 91
Szablony tekstu
string.Templates




Podobną funkcjonalność do formatowania napisów daje klasa
string.Template:
      from string import Template
      msg = Template("namehasn messages")
      print(msg.substitute(name="Dave",n=37)




                                                         .   .      .      .       .    .

    Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   38 / 91
Table of Contents

1.   Wstęp

2.   Python 3

3.   Tekst

4.   Formatowanie tesktu

5.   Dane binarne

6.   Moduł I/O

7.   System Interface

8.   Projektowanie bibliotek

                                                          .   .      .      .       .    .

     Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   39 / 91
Bytes
definiowanie




Definiowanie “bytes”
     a   =   b"ACME␣50␣91.10"     # Byte string literal
     b   =   bytes([1,2,3,4,5])   # From a list of integers
     c   =   bytes(10)            # An array of 10 zero-bytes
     d   =   bytes("Jalapeño","utf-8") # Encoded from string




                                                          .   .      .      .       .    .

   Robert Zaremba (Scale it)     Python Zaawansowane IO       Wrocław 2011 listopad 10   40 / 91
Bytes
definiowanie




Definiowanie “bytes”
     a   =   b"ACME␣50␣91.10"     # Byte string literal
     b   =   bytes([1,2,3,4,5])   # From a list of integers
     c   =   bytes(10)            # An array of 10 zero-bytes
     d   =   bytes("Jalapeño","utf-8") # Encoded from string

Tworzenie z stringu zawierającego liczbę hexadecimal
         e = bytes.fromhex("48656c6c6f")




                                                          .   .      .      .       .    .

   Robert Zaremba (Scale it)     Python Zaawansowane IO       Wrocław 2011 listopad 10   40 / 91
Bytes
właściwości




Bytes posiada standardowe metody napisów
      >>> s = b"ACME␣50␣91.10"
      >>> s.split()
      [b'ACME', b'50', b'91.10']
      >>> s.lower()
      b'acme␣50␣91.10'
      >>> s[5:7]
      b'50'




                                                         .   .      .      .       .    .

    Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   41 / 91
Bytes
właściwości




Bytes posiada standardowe metody napisów
      >>> s = b"ACME␣50␣91.10"
      >>> s.split()
      [b'ACME', b'50', b'91.10']
      >>> s.lower()
      b'acme␣50␣91.10'
      >>> s[5:7]
      b'50'

Bytes tak samo jak napisy są niemutowalne




                                                         .   .      .      .       .    .

    Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   41 / 91
Bytes
właściwości




      bytes to tablica int-ów
              >>> s = b"ACME␣50␣91.10"
              >>> s[0]
              65
              >>> s[1]
              67




                                                           .   .      .      .       .    .

    Robert Zaremba (Scale it)     Python Zaawansowane IO       Wrocław 2011 listopad 10   42 / 91
Bytes
właściwości




      bytes to tablica int-ów
              >>> s = b"ACME␣50␣91.10"
              >>> s[0]
              65
              >>> s[1]
              67

      bytes to standardowa struktura operacji I/O




                                                           .   .      .      .       .    .

    Robert Zaremba (Scale it)     Python Zaawansowane IO       Wrocław 2011 listopad 10   42 / 91
Bytes
Problemy




     Portowanie kodu z Python2 do Python3
            data = s.recv(1024)
            if data[0] == b'+':       # ERROR!
              ...
            # fix
            data = s.recv(1024)
            if data[0] == 0x2b:       # CORRECT
               ...




                                                           .   .      .      .       .    .

   Robert Zaremba (Scale it)      Python Zaawansowane IO       Wrocław 2011 listopad 10   43 / 91
Bytes
Portowanie




     Nie potrzeba używać metody ord




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   44 / 91
Bytes
Portowanie




     Nie potrzeba używać metody ord
     konwersja obiektów do “bytes” - postać binarna obiektów:
             >>> x = 7
             >>> bytes(x)
             b'x00x00x00x00x00x00x00'
             >>> str(x).encode('ascii')
             b'7'




                                                          .   .      .      .       .    .

   Robert Zaremba (Scale it)     Python Zaawansowane IO       Wrocław 2011 listopad 10   44 / 91
bytearray

    bytearray to mutowalne “bytes”
           >>> s = bytearray(b"ACME␣50␣91.10")
           >>> s[:4] = b"PYTHON"
           >>> s
           bytearray(b"PYTHON␣50␣91.10")
           >>> s[0] = 0x70                 # Must assign integers
           >>> s
           bytearray(b'pYTHON␣50␣91.10")




                                                        .   .      .      .       .    .

  Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   45 / 91
bytearray

    bytearray to mutowalne “bytes”
           >>> s = bytearray(b"ACME␣50␣91.10")
           >>> s[:4] = b"PYTHON"
           >>> s
           bytearray(b"PYTHON␣50␣91.10")
           >>> s[0] = 0x70                 # Must assign integers
           >>> s
           bytearray(b'pYTHON␣50␣91.10")

    zawiera wiele operacji “listowych”
           >>> s.append(23)
           >>> s.append(45)
           >>> s.extend([1,2,3,4])
           >>> s
           bytearray(b'ACME␣50␣91.10x17-x01x02x03x04')


                                                        .   .      .      .       .    .

  Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   45 / 91
Bytes a Unicode

    bytes nie służy do przetwarzania tekstu




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   46 / 91
Bytes a Unicode

    bytes nie służy do przetwarzania tekstu
    można użyć ich do tekstu - grozi to strasznym problemom (s[1] to nie
    litera, a część kodu litery)




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   46 / 91
Bytes a Unicode

    bytes nie służy do przetwarzania tekstu
    można użyć ich do tekstu - grozi to strasznym problemom (s[1] to nie
    litera, a część kodu litery)
    Python3 jasno oddziela tekst od ciągu bajtów (unicode vs bytes)




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   46 / 91
Bytes a Unicode

    bytes nie służy do przetwarzania tekstu
    można użyć ich do tekstu - grozi to strasznym problemom (s[1] to nie
    litera, a część kodu litery)
    Python3 jasno oddziela tekst od ciągu bajtów (unicode vs bytes)
           >>> s = b"ACME␣50␣91.10"
           >>> 'ACME' in s
           Traceback (most recent call last):
           File "<stdin>", line 1, in <module>
           TypeError: Type str doesn't␣support␣the␣buffer␣API




                                                        .   .      .      .       .    .

  Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   46 / 91
Bytes a Unicode

    bytes nie służy do przetwarzania tekstu
    można użyć ich do tekstu - grozi to strasznym problemom (s[1] to nie
    litera, a część kodu litery)
    Python3 jasno oddziela tekst od ciągu bajtów (unicode vs bytes)
           >>> s = b"ACME␣50␣91.10"
           >>> 'ACME' in s
           Traceback (most recent call last):
           File "<stdin>", line 1, in <module>
           TypeError: Type str doesn't␣support␣the␣buffer␣API

    print() powiniena być tylko używana z tekstem (unicode)




                                                        .   .      .      .       .    .

  Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   46 / 91
Bytes a Unicode

    bytes nie służy do przetwarzania tekstu
    można użyć ich do tekstu - grozi to strasznym problemom (s[1] to nie
    litera, a część kodu litery)
    Python3 jasno oddziela tekst od ciągu bajtów (unicode vs bytes)
           >>> s = b"ACME␣50␣91.10"
           >>> 'ACME' in s
           Traceback (most recent call last):
           File "<stdin>", line 1, in <module>
           TypeError: Type str doesn't␣support␣the␣buffer␣API

    print() powiniena być tylko używana z tekstem (unicode)
    Bytes nie wspierają metody format



                                                        .   .      .      .       .    .

  Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   46 / 91
Bytes a Unicode

    bytes nie służy do przetwarzania tekstu
    można użyć ich do tekstu - grozi to strasznym problemom (s[1] to nie
    litera, a część kodu litery)
    Python3 jasno oddziela tekst od ciągu bajtów (unicode vs bytes)
           >>> s = b"ACME␣50␣91.10"
           >>> 'ACME' in s
           Traceback (most recent call last):
           File "<stdin>", line 1, in <module>
           TypeError: Type str doesn't␣support␣the␣buffer␣API

    print() powiniena być tylko używana z tekstem (unicode)
    Bytes nie wspierają metody format
    Wiele funkcji operujących na tekście nie akcepują bytes (np:
    time.strptime)
                                                        .   .      .      .       .    .

  Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   46 / 91
Gdzie używać bytes




    bytes nadają się do niskopoziomowych operacji I/O. (przekazywanie
    wiadomości, systemy wbudowane, obliczenia rozproszone …)




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   47 / 91
Użycie bytes
    konkatenacja ciągu w Python2
           chunks = []
           while True:
           chunk = s.recv(BUFSIZE)
           if not chunk:
           break
           chunks.append(chunk)
           msg = b"".join(chunks)




                                                        .   .      .      .       .    .

  Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   48 / 91
Użycie bytes
    konkatenacja ciągu w Python2
           chunks = []
           while True:
           chunk = s.recv(BUFSIZE)
           if not chunk:
           break
           chunks.append(chunk)
           msg = b"".join(chunks)

    konkatenacja ciągu w Python3
           msg = bytearray()
           while True:
           chunk = s.recv(BUFSIZE)
           if not chunk:
           break
           msg.extend(chunk)


                                                        .   .      .      .       .    .

  Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   48 / 91
Użycie bytes
    konkatenacja ciągu w Python2
           chunks = []
           while True:
           chunk = s.recv(BUFSIZE)
           if not chunk:
           break
           chunks.append(chunk)
           msg = b"".join(chunks)

    konkatenacja ciągu w Python3
           msg = bytearray()
           while True:
           chunk = s.recv(BUFSIZE)
           if not chunk:
           break
           msg.extend(chunk)

    wielka wydajność operacji na bytes i bytearray
                                                        .   .      .      .       .    .

  Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   48 / 91
Użycie bytes
przekazywanie wiadomości




Przekazywanie wiadomości.
     objs = [ ... ]          # List of tuples to pack
     msg = bytearray()       # Empty message
     # First pack the number of objects
     msg.extend(struct.pack("<I",len(objs)))
     for x in objs:                     # Incrementally pack each object
        msg.extend(struct.pack(fmt, *x))

     f.write(msg)              # Do something with the message




                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   49 / 91
Użycie bytes
XOR - cipher




kodowanie XOR
     >>> s = b"Hello␣World"
     >>> t = bytes(x^42 for x in s)
     >>> t
     b'bOFFEn}EXFN'
     >>> bytes(x^42 for x in t)
     b'Hello␣World'




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   50 / 91
Użycie bytes
suma kontrolna




dołączanie sumy kontrolnej
     chk = 0
     for n in msg:
         chk ^= n
     msg.append(chk)




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   51 / 91
Bufory
podobieństwa bytearray         buffers




     bufor to ciągły obszar pamięci
     bufferarray() jest przykładem buforu




                                                                 .   .      .      .       .    .

   Robert Zaremba (Scale it)            Python Zaawansowane IO       Wrocław 2011 listopad 10   52 / 91
Bufory
podobieństwa bytearray         buffers




     bufor to ciągły obszar pamięci
     bufferarray() jest przykładem buforu
     przykład:
            array.array("i", [1,2,3,4,5])
            numpy.array([1,2,3,4,5])
            ctypes.ARRAY(ctypes.c_int,5)(1,2,3,4,5)




                                                                 .   .      .      .       .    .

   Robert Zaremba (Scale it)            Python Zaawansowane IO       Wrocław 2011 listopad 10   52 / 91
Bufory
podobieństwa bytearray         buffers




     bufor to ciągły obszar pamięci
     bufferarray() jest przykładem buforu
     przykład:
            array.array("i", [1,2,3,4,5])
            numpy.array([1,2,3,4,5])
            ctypes.ARRAY(ctypes.c_int,5)(1,2,3,4,5)

     można powiedzieć że powyższe struktury są zamienne z typem bytes




                                                                 .   .      .      .       .    .

   Robert Zaremba (Scale it)            Python Zaawansowane IO       Wrocław 2011 listopad 10   52 / 91
Memory View



    memoryview to “nakładka na bufor” - patrz help()
           >>> a = bytearray(b'Hello␣World')
           >>> b = memoryview(a)
           >>> b
           <memory at 0x1007014d0>
           >>> b[-5:] = b'There'
           >>> a
           bytearray(b'Hello␣There')




                                                        .   .      .      .       .    .

  Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   53 / 91
Memory View



    memoryview to “nakładka na bufor” - patrz help()
           >>> a = bytearray(b'Hello␣World')
           >>> b = memoryview(a)
           >>> b
           <memory at 0x1007014d0>
           >>> b[-5:] = b'There'
           >>> a
           bytearray(b'Hello␣There')

    jest bardzo niskopoziomową strukturą




                                                        .   .      .      .       .    .

  Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   53 / 91
Table of Contents

1.   Wstęp

2.   Python 3

3.   Tekst

4.   Formatowanie tesktu

5.   Dane binarne

6.   Moduł I/O

7.   System Interface

8.   Projektowanie bibliotek

                                                          .   .      .      .       .    .

     Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   54 / 91
implementacja I/O




    w Pytonie2 I/O jest oparte o c I/O
    python “file” to tylko cienka nakładka na C “FILE”




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   55 / 91
implementacja I/O




    w Pytonie2 I/O jest oparte o c I/O
    python “file” to tylko cienka nakładka na C “FILE”
    Python3 wprowadza swoją strukturę
    jak było już powiedziane Python3 przeimplementował system I/O




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   55 / 91
funkcja open()


    użycie podobnie jak wcześniej
    obiekt zwracany przez open różni się w zależności o ustawionego
    argumentu file mode




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   56 / 91
funkcja open()


    użycie podobnie jak wcześniej
    obiekt zwracany przez open różni się w zależności o ustawionego
    argumentu file mode
    przykład poniżej
           >>> open("foo.txt","rt")
           <_io.TextIOWrapper name='foo.txt' encoding='UTF-8'>
           >>> open("foo.txt","rb")
           <_io.BufferedReader name='foo.txt'>
           >>> open("foo.txt","rb",buffering=0)
           <_io.FileIO name='foo.txt' mode='rb'>




                                                        .   .      .      .       .    .

  Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   56 / 91
funkcja open()


    użycie podobnie jak wcześniej
    obiekt zwracany przez open różni się w zależności o ustawionego
    argumentu file mode
    przykład poniżej
           >>> open("foo.txt","rt")
           <_io.TextIOWrapper name='foo.txt' encoding='UTF-8'>
           >>> open("foo.txt","rb")
           <_io.BufferedReader name='foo.txt'>
           >>> open("foo.txt","rb",buffering=0)
           <_io.FileIO name='foo.txt' mode='rb'>

    task: uruchomienie tego w python2


                                                        .   .      .      .       .    .

  Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   56 / 91
Moduł I/O


    moduł io składa się z różny klas:
    FileIO
    BufferedReader
    BufferedWriter
    BufferedRWPair
    BufferedRandom
    TextIOWrapper
    BytesIO
    StringIO

    każda klasa implementuje inny rodzaj I/O
    każda klasa dodaje pewien zbiór właściwości


                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   57 / 91
Moduł I/O
warstwy I/O




     otwarcie pliku powoduje kolejno tworzenie obiektów
     open("foo.txt", "rt")
     (TextIOWrapper → BufferedReader → FileIO
     w Javie jest podobnie




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   58 / 91
Moduł I/O
FileIO




         obiekt reprezentujący surowy niebuforowany obiekt binary
         (FileIO(name [, mode [, closefd]])
     name nazwa pliku lub numer fd
    mode ’r’, ’w’, ’a’, ’r+’, …
   closefd flaga kontrolująca czy metoda close() była wywołana.




                                                          .   .      .      .       .    .

    Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   59 / 91
Moduł I/O
FileIO




         obiekt reprezentujący surowy niebuforowany obiekt binary
         (FileIO(name [, mode [, closefd]])
     name nazwa pliku lub numer fd
    mode ’r’, ’w’, ’a’, ’r+’, …
   closefd flaga kontrolująca czy metoda close() była wywołana.
         FileIO jest bezpośrednio zaimplemenowany na podstawie
         systemowych funkcji read(), write()
         bezpośrednio daje dostęp do niskopoziomowych wywołań
         systemowych na deskryptorze pliku




                                                          .   .      .      .       .    .

    Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   59 / 91
Moduł I/O
FileIO




         obiekt reprezentujący surowy niebuforowany obiekt binary
         (FileIO(name [, mode [, closefd]])
     name nazwa pliku lub numer fd
    mode ’r’, ’w’, ’a’, ’r+’, …
   closefd flaga kontrolująca czy metoda close() była wywołana.
         FileIO jest bezpośrednio zaimplemenowany na podstawie
         systemowych funkcji read(), write()
         bezpośrednio daje dostęp do niskopoziomowych wywołań
         systemowych na deskryptorze pliku
         w tym: częściowy odczyt / zapis, zwracanie systemowych kodów
         błędów, dostęp blokowany, nieblokowany (asynchroniczny)


                                                          .   .      .      .       .    .

    Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   59 / 91
FileIO
używanie




     Python2 - moduł os
            fd = os.open("somefile",os.O_RDONLY)
            data = os.read(fd,4096)
            os.lseek(fd,16384,os.SEEK_SET)



     Python3 - obiekt FileIO
            f = io.FileIO("somefile","r")
            data = f.read(4096)
            f.seek(16384,os.SEEK_SET)




                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   60 / 91
BufferedIO


    klasy implementujące buforowany I/O
           BufferedReader(f [, buffer_size])
           BufferedWriter(f [, buffer_size [, max_buffer_size]])
           BufferedRWPair(f_read, f_write
                [, buffer_size [, max_buffer_size]])
           BufferedRandom(f [, buffer_size [, max_buffer_size]])




                                                        .   .      .      .       .    .

  Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   61 / 91
BufferedIO


    klasy implementujące buforowany I/O
           BufferedReader(f [, buffer_size])
           BufferedWriter(f [, buffer_size [, max_buffer_size]])
           BufferedRWPair(f_read, f_write
                [, buffer_size [, max_buffer_size]])
           BufferedRandom(f [, buffer_size [, max_buffer_size]])

    każda z poniższych klas jest implementacją opartą o FileIO
           f = io.FileIO("foo.txt")   # Open the file (raw I/O)
           g = io.BufferedReader(f)   # Put buffering around it
           f = io.BufferedReader(io.FileIO("foo.txt")) # Alternative




                                                        .   .      .      .       .    .

  Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   61 / 91
Bufory




    Bufory są kontrolowane przez dwa parametry:
    buffer_size, max_buffer_size
    buffer_size - ilość danych jaką bufor może przechować zanim “opróżni
    się” do I/O
    max_buffer_size - pojemność jaką posiada bufor zanim się zablokuje
    (domyślnie 2x buffer_size)
    Aby bufor zaakceptował więcej danych, należy wcześniej go opróżnić.




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   62 / 91
Bufory
operacje na buforach



      buffer readers:
            f.peek([n])        # Return up to n bytes of data without
            # advancing the    file pointer
            f.read([n])        # Return n bytes of data as bytes
            f.read1([n])       # Read up to n bytes using a single
            # read() system    call




                                                            .   .      .      .       .    .

   Robert Zaremba (Scale it)       Python Zaawansowane IO       Wrocław 2011 listopad 10   63 / 91
Bufory
operacje na buforach



      buffer readers:
            f.peek([n])        # Return up to n bytes of data without
            # advancing the    file pointer
            f.read([n])        # Return n bytes of data as bytes
            f.read1([n])       # Read up to n bytes using a single
            # read() system    call

      buffer writers
            f.write(bytes)      # Write bytes
            f.flush()           # Flush output buffers




                                                            .   .      .      .       .    .

   Robert Zaremba (Scale it)       Python Zaawansowane IO       Wrocław 2011 listopad 10   63 / 91
Bufory
operacje na buforach



      buffer readers:
            f.peek([n])        # Return up to n bytes of data without
            # advancing the    file pointer
            f.read([n])        # Return n bytes of data as bytes
            f.read1([n])       # Read up to n bytes using a single
            # read() system    call

      buffer writers
            f.write(bytes)      # Write bytes
            f.flush()           # Flush output buffers

      inne operacje:
      seek, tell, close

                                                            .   .      .      .       .    .

   Robert Zaremba (Scale it)       Python Zaawansowane IO       Wrocław 2011 listopad 10   63 / 91
UWAGA
dla obiektów “pliko podobnych”




     Jeśli używamy obiektów “pliko podobnych” powinniśmy używać
     metody
     readl()
     jeśli pominiemy tą uwagę nasz program może się rozpaść jeśli inny
     wątek / program będzie chciał się odwołać do tego samego pliku




                                                          .   .      .      .       .    .

   Robert Zaremba (Scale it)     Python Zaawansowane IO       Wrocław 2011 listopad 10   64 / 91
TextIOWrapper

    obiekt implementujący text-based I/O
    TextIOWrapper(buffered [, encoding [, errors
    [, newline [, line_buffering]]]])
    buffered          - A buffered file object
    encoding          - Text encoding (e.g., 'utf-8')
    errors           - Error handling policy (e.g. 'strict')
    newline           - '', 'n', 'r', 'rn', or None
    line_buffering    - Flush output after each line (False)

    jest jedną z warstw buforowanych strumieni I/O
           f = io.FileIO("foo.txt")        # Open the file (raw I/O)
           g = io.BufferedReader(f)        # Put buffering around it
           h = io.TextIOWrapper(g,"utf-8") # Text I/O wrapper


                                                        .   .      .      .       .    .

  Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   65 / 91
Text
obsługa znaku nowej linii




      Domyślnie pliki są otwierane w trybie ”‘universal newline”’ - znaki
      nowej linii są mapowane do znaku n




                                                         .   .      .      .       .    .

    Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   66 / 91
Text
obsługa znaku nowej linii




      Domyślnie pliki są otwierane w trybie ”‘universal newline”’ - znaki
      nowej linii są mapowane do znaku n
      aby pozostawić oryginalny znak nowej linii, należy użyć funkcji open z
      dodatkowym argumentem newline=''




                                                         .   .      .      .       .    .

    Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   66 / 91
Text
obsługa znaku nowej linii




      Domyślnie pliki są otwierane w trybie ”‘universal newline”’ - znaki
      nowej linii są mapowane do znaku n
      aby pozostawić oryginalny znak nowej linii, należy użyć funkcji open z
      dodatkowym argumentem newline=''
      jeśli nie wymusimy formatu znaku nowej linii (poprzez użycie
      argumentu newline w funkcji open), wtedy podczas zapisu używany
      jest os.linesep jako znak nowej linii.




                                                         .   .      .      .       .    .

    Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   66 / 91
Text
obsługa kodowań




     w Python2 aby automatycznie zdekodować zawartość pliku podczas
     czytania używany jest moduł codecs




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   67 / 91
Text
obsługa kodowań




     w Python2 aby automatycznie zdekodować zawartość pliku podczas
     czytania używany jest moduł codecs
     w Python3 nie ma potrzeby używania codecs.
     W pełni zastępuje go TextIOWrapper




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   67 / 91
Text
obsługa kodowań




     w Python2 aby automatycznie zdekodować zawartość pliku podczas
     czytania używany jest moduł codecs
     w Python3 nie ma potrzeby używania codecs.
     W pełni zastępuje go TextIOWrapper
     TextIOWrapper jest znacznie szybszy niż codecs
            for line in open("biglog.txt",encoding="utf-8"):            # 3.8 sec
              pass
            f = codecs.open("biglog.txt",encoding="utf-8")
            for line in f:                                              # 53.3 sec
              pass




                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   67 / 91
open()
Porównanie




     typ obiektu zwracanego przez funkcję open zależy od parametrów.
                       mode                   buffering       Result
                       any binary             0              FileIO
                       ”rb”                   != 0           BufferedReader
                       ”wb”, ”ab”             != 0           BufferedWriter
                       ”rb”, ”wb+”, ”ab+”     != 0           BufferedRandom
                       any text               != 0           TextIOWrapper




                                                             .    .      .      .       .    .

   Robert Zaremba (Scale it)        Python Zaawansowane IO        Wrocław 2011 listopad 10   68 / 91
open()
Porównanie




     typ obiektu zwracanego przez funkcję open zależy od parametrów.
                       mode                   buffering       Result
                       any binary             0              FileIO
                       ”rb”                   != 0           BufferedReader
                       ”wb”, ”ab”             != 0           BufferedWriter
                       ”rb”, ”wb+”, ”ab+”     != 0           BufferedRandom
                       any text               != 0           TextIOWrapper
     Uwaga: niektóre kombinacje są nielegalne, a ich użycie spowoduje
     rzucenie wyjątku (np: unbuffered text)


                                                             .    .      .      .       .    .

   Robert Zaremba (Scale it)        Python Zaawansowane IO        Wrocław 2011 listopad 10   68 / 91
I/O Stack
przechodzenie po stosie I/O



      Scenariusz: mamy plik otwarty w text-mode, ale chcemy go czytać w
      binary-mode.




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   69 / 91
I/O Stack
przechodzenie po stosie I/O



      Scenariusz: mamy plik otwarty w text-mode, ale chcemy go czytać w
      binary-mode.
      warstwy wyższe zawierają warstwy niższe. Czyli do bardziej natywnych
      obiektów i/o możemy się dostać przez pola obiektów wyższych:

            TextIOWrapper
                                 .buffer
                                ?
            BufferedReader
                                 .raw
                                ?
                       FileIO

                                                                 .   .      .      .       .    .

   Robert Zaremba (Scale it)            Python Zaawansowane IO       Wrocław 2011 listopad 10   69 / 91
I/O Stack
przechodzenie po stosie I/O - przykład




Pisanie danych binarnych do sys.stdout.
Pomysły?




                                                            .   .      .      .       .    .

    Robert Zaremba (Scale it)      Python Zaawansowane IO       Wrocław 2011 listopad 10   70 / 91
I/O Stack
przechodzenie po stosie I/O - przykład




Pisanie danych binarnych do sys.stdout.
Pomysły?
      >>> import sys
      >>> sys.stdout.write(b"Hello␣Worldn")
      Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      TypeError: must be str, not bytes
      >>> sys.stdout.buffer.write(b"Hello␣Worldn")
      Hello World
      12




                                                            .   .      .      .       .    .

    Robert Zaremba (Scale it)      Python Zaawansowane IO       Wrocław 2011 listopad 10   70 / 91
I/O Stack
UWAGA - warstwy!


Przechodzenie po warstwach może powodować błędy gdy pracujemy z
objektami typu pliki.
     >>> import io
     >>> from urllib.request import urlopen
     >>> u = io.TextIOWrapper(
     urlopen("http://www.python.org"),
     encoding='latin1')
     >>> text = u.read()
     >>> u = io.TextIOWrapper(
     urlopen("http://www.python.org"),
     encoding='latin1')
     >>> line = u.readline()
     Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
     AttributeError: 'HTTPResponse' object has no
     attribute 'read1'

                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   71 / 91
I/O Performance
odczyt




     odczyt 100 Mb tekstu z pliku data = open("big.txt").read()
            Python 2.7.1:               0.14s
            Python 3.2 (UCS-2, UTF-8) : 0.90s
            Python 3.2 (UCS-4, UTF-8) : 1.56s




                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   72 / 91
I/O Performance
odczyt




     odczyt 100 Mb tekstu z pliku data = open("big.txt").read()
            Python 2.7.1:               0.14s
            Python 3.2 (UCS-2, UTF-8) : 0.90s
            Python 3.2 (UCS-4, UTF-8) : 1.56s

     odczyt 100 Mb danych binarnych
     data = open("big.bin","rb").read()
            Python 2.7.1        : 0.16s
            Python 3.2 (binary) : 0.14s




                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   72 / 91
I/O Performance
zapis




        zapis 100 Mb tekstu do pliku open("foo.txt","wt").write(text)
             Python 2.7.1       : 1.73s
             Python 3.2 (UTF-8) : 1.85s




                                                          .   .      .      .       .    .

    Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   73 / 91
I/O Performance
zapis




        zapis 100 Mb tekstu do pliku open("foo.txt","wt").write(text)
             Python 2.7.1       : 1.73s
             Python 3.2 (UTF-8) : 1.85s

        zapis 100 Mb danych binarnych
        data = open("big.bin","wb").write(data)
             Python 2.7.1        : 1.79s
             Python 3.2 (binary) : 1.80s




                                                          .   .      .      .       .    .

    Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   73 / 91
I/O Performance
iteracja




      zapis 100 Mb tekstu do pliku
      for line in open("biglog.txt"): pass
             Python 2.7.1              : 0.25s
             Python 3.2 (UCS-2, UTF-8) : 0.57s
             Python 3.2 (UCS-4, UTF-8) : 0.82s




                                                          .   .      .      .       .    .

    Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   74 / 91
I/O Performance
iteracja




      zapis 100 Mb tekstu do pliku
      for line in open("biglog.txt"): pass
             Python 2.7.1              : 0.25s
             Python 3.2 (UCS-2, UTF-8) : 0.57s
             Python 3.2 (UCS-4, UTF-8) : 0.82s

      zapis 100 Mb danych binarnych
      for line in open("biglog.txt","rb"): pass
             Python 2.7.1        : 0.25s
             Python 3.2 (binary) : 0.29s




                                                          .   .      .      .       .    .

    Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   74 / 91
I/O - komentarze




    odczyt zapis tak czy siak sprowadza się do zapisu bajtów




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   75 / 91
I/O - komentarze




    odczyt zapis tak czy siak sprowadza się do zapisu bajtów
    aby odczytać tekst, każdy znak musi zostać skopiowany do ”‘intów”’




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   75 / 91
I/O - komentarze




    odczyt zapis tak czy siak sprowadza się do zapisu bajtów
    aby odczytać tekst, każdy znak musi zostać skopiowany do ”‘intów”’
    aby uniknąć tych kopiowań należy nie korzystać z trybu tekstowego
    (nie konwertować bytes do unicode).
    Jednak nie zawsze oznacza to praktycznie rozwiązanie.




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   75 / 91
I/O - komentarze




    odczyt zapis tak czy siak sprowadza się do zapisu bajtów
    aby odczytać tekst, każdy znak musi zostać skopiowany do ”‘intów”’
    aby uniknąć tych kopiowań należy nie korzystać z trybu tekstowego
    (nie konwertować bytes do unicode).
    Jednak nie zawsze oznacza to praktycznie rozwiązanie.
    TEKST ZAWSZE POWINIEN BYĆ PRZETWARZANY ZA
    POMOCĄ UNICODE




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   75 / 91
I/O, optymalizacja pracy z unicode




Jeśli mamy do czynienia z olbrzymią ilością TEKSTU jednobajtowego
(ASCII, Latin-x, ...), a mammy małą ilość dostępnej pamięci można użyć
paru optymalizacji
    Odłożyć konwersje do Unicode jak najpóźniej się da




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   76 / 91
I/O, optymalizacja pracy z unicode




Jeśli mamy do czynienia z olbrzymią ilością TEKSTU jednobajtowego
(ASCII, Latin-x, ...), a mammy małą ilość dostępnej pamięci można użyć
paru optymalizacji
    Odłożyć konwersje do Unicode jak najpóźniej się da
    parsowanie tekstu jednobajtowego można dokonać na poziomie bytes.




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   76 / 91
I/O, optymalizacja pracy z unicode




Jeśli mamy do czynienia z olbrzymią ilością TEKSTU jednobajtowego
(ASCII, Latin-x, ...), a mammy małą ilość dostępnej pamięci można użyć
paru optymalizacji
    Odłożyć konwersje do Unicode jak najpóźniej się da
    parsowanie tekstu jednobajtowego można dokonać na poziomie bytes.
    Przykład: parsowanie logów




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   76 / 91
I/O, optymalizacja pracy z unicode
Przykład




Znaleźć wszystkie URL, które spowodowały status 404 w logach Apache.
Pomysły?




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   77 / 91
I/O, optymalizacja pracy z unicode
Przykład




Znaleźć wszystkie URL, które spowodowały status 404 w logach Apache.
Pomysły?
     error_404_urls = set()
     for line in open("biglog.txt","rb"):
         fields = line.split()
         if fields[-2] == b'404':
             error_404_urls.add(fields[-4])
     error_404_urls = {n.decode('latin-1')
                      for n in error_404_urls }
     for name in error_404_urls:
         print(name)




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   77 / 91
Table of Contents

1.   Wstęp

2.   Python 3

3.   Tekst

4.   Formatowanie tesktu

5.   Dane binarne

6.   Moduł I/O

7.   System Interface

8.   Projektowanie bibliotek

                                                          .   .      .      .       .    .

     Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   78 / 91
operacje systemowe


    Do obsługi operacji systemowych Python wykorzystuje zapytania
    systemowe z biblioteki C




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   79 / 91
operacje systemowe


    Do obsługi operacji systemowych Python wykorzystuje zapytania
    systemowe z biblioteki C
    Przykład wywołania zapytania systemowe w POSIX na Unixie:
        int fd = open(filename, O_RDONLY);




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   79 / 91
operacje systemowe


    Do obsługi operacji systemowych Python wykorzystuje zapytania
    systemowe z biblioteki C
    Przykład wywołania zapytania systemowe w POSIX na Unixie:
        int fd = open(filename, O_RDONLY);
    atrybuty są przekazywane do zapytań systemowych (nazwy plików,
    programów, …) jako ciągi znaków (w C - char*, Python - bytes)




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   79 / 91
operacje systemowe


    Do obsługi operacji systemowych Python wykorzystuje zapytania
    systemowe z biblioteki C
    Przykład wywołania zapytania systemowe w POSIX na Unixie:
        int fd = open(filename, O_RDONLY);
    atrybuty są przekazywane do zapytań systemowych (nazwy plików,
    programów, …) jako ciągi znaków (w C - char*, Python - bytes)
    Bytes są używane w zmiennych środowiskowych, argumentach
    wywołania (command line arguments)




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   79 / 91
operacje systemowe


    Do obsługi operacji systemowych Python wykorzystuje zapytania
    systemowe z biblioteki C
    Przykład wywołania zapytania systemowe w POSIX na Unixie:
        int fd = open(filename, O_RDONLY);
    atrybuty są przekazywane do zapytań systemowych (nazwy plików,
    programów, …) jako ciągi znaków (w C - char*, Python - bytes)
    Bytes są używane w zmiennych środowiskowych, argumentach
    wywołania (command line arguments)
    Jak Python integruje swoje stringi (Unicode) z byte-oriented
    interfejsem systemowym?



                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   79 / 91
operacje systemowe
kodowanie argumentów




     Standardowo python3 koduje wszystkie parametry ”‘tekstowe”’ w
     UTF-8




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   80 / 91
operacje systemowe
kodowanie argumentów




     Standardowo python3 koduje wszystkie parametry ”‘tekstowe”’ w
     UTF-8
     ogólnie jest to bezpieczne założenie.




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   80 / 91
operacje systemowe
kodowanie argumentów




     Standardowo python3 koduje wszystkie parametry ”‘tekstowe”’ w
     UTF-8
     ogólnie jest to bezpieczne założenie.
     podobnie z argumentami wywołania i zmiennymi środowiskowymi -
       Python3 dekoduje je za pomocą UTF-8.




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   80 / 91
operacje systemowe
kodowanie argumentów




     Standardowo python3 koduje wszystkie parametry ”‘tekstowe”’ w
     UTF-8
     ogólnie jest to bezpieczne założenie.
     podobnie z argumentami wywołania i zmiennymi środowiskowymi -
       Python3 dekoduje je za pomocą UTF-8.
     Jest to dość subtelne zachowanie - gdyż zakłada że wszystkie opcje
     parametry systemowe są kodowane w UTF-8




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   80 / 91
operacje systemowe
kodowanie argumentów




     Standardowo python3 koduje wszystkie parametry ”‘tekstowe”’ w
     UTF-8
     ogólnie jest to bezpieczne założenie.
     podobnie z argumentami wywołania i zmiennymi środowiskowymi -
       Python3 dekoduje je za pomocą UTF-8.
     Jest to dość subtelne zachowanie - gdyż zakłada że wszystkie opcje
     parametry systemowe są kodowane w UTF-8
     ale niekoniecznie tak musi być




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   80 / 91
operacje systemowe - kodowanie nazw
Przykład - błąd w nazwie pliku

      Za pomocą Python2 stworzymy plik w systemie Linux, którego nazwa
      będzie zawierać jeden znak spoza ASCII:
             >>> f = open("jalapexf1o.txt","w")
             >>> f.write("Bwahahahaha!n")
             >>> f.close()




                                                          .   .      .      .       .    .

    Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   81 / 91
operacje systemowe - kodowanie nazw
Przykład - błąd w nazwie pliku

      Za pomocą Python2 stworzymy plik w systemie Linux, którego nazwa
      będzie zawierać jeden znak spoza ASCII:
             >>> f = open("jalapexf1o.txt","w")
             >>> f.write("Bwahahahaha!n")
             >>> f.close()

      Python3 nie będzie w stanie otworzyć tego pliku.
             >>> f = open("jalapexf1o.txt")
             Traceback (most recent call last):
             ...
             IOError: [Errno 2] No such file or directory: 'jalapeño.txt'

      Powód: nazwa pliku po zakodowaniu w UTF-8 nie odpowiada nazwie
      pliku w systemie:
      ”jalapexf1o.txt” → UTF-8 coder → b”jalapec3xb1o.txt”

                                                          .   .      .      .       .    .

    Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   81 / 91
operacje systemowe - kodowanie nazw
Przykład - błąd w nazwie pliku

      Za pomocą Python2 stworzymy plik w systemie Linux, którego nazwa
      będzie zawierać jeden znak spoza ASCII:
             >>> f = open("jalapexf1o.txt","w")
             >>> f.write("Bwahahahaha!n")
             >>> f.close()

      Python3 nie będzie w stanie otworzyć tego pliku.
             >>> f = open("jalapexf1o.txt")
             Traceback (most recent call last):
             ...
             IOError: [Errno 2] No such file or directory: 'jalapeño.txt'

      Powód: nazwa pliku po zakodowaniu w UTF-8 nie odpowiada nazwie
      pliku w systemie:
      ”jalapexf1o.txt” → UTF-8 coder → b”jalapec3xb1o.txt”
      Co się stanie gdy w directory listing będzie nazwa pliku nie
      UTF-8?                                              .   .      .      .       .    .

    Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   81 / 91
operacje systemowe - kodowanie nazw
argumenty jako Bytes




     Można użyć bytes zamiast unicode jako argumenty do wywołań
     systemowych.
            >>> f = open(b"jalapexf1o.txt")
            >>> files = glob.glob(b"*.txt")
            >>> files
            [b'jalapexf1o.txt', b'spam.txt']




                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   82 / 91
operacje systemowe - kodowanie nazw
argumenty jako Bytes




     Można użyć bytes zamiast unicode jako argumenty do wywołań
     systemowych.
            >>> f = open(b"jalapexf1o.txt")
            >>> files = glob.glob(b"*.txt")
            >>> files
            [b'jalapexf1o.txt', b'spam.txt']

     Jeśli użyjemy bytes do wywołania systemowego, wtedy ciąg ten nie
     będzie w ogóle kodowany, oraz zwracane wyniki będą podawane jako
     bytes.



                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   82 / 91
Surrogate Encoding




    W Pythonie3.1 każdy nie dekodowalny (nie ASCII) znak w nazwie
    pliku lub parametrze interfejsu systemowego jest tłumaczony przez
    Surrogate Encoding
    Jest to specyficzny dla Pythona trik, który zapobiega błędom podczas
    wywołań systemowych przy obsłudze argumentów które nie są
    poprawnymi ciągami UTF-8.




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   83 / 91
Surrogate Encoding
definicja




      Każdy bajt ∈ [0x80; 0xff] zamieniany jest na znak unicode
      ∈ [U + DC80; U + DCFF]




                                                         .   .      .      .       .    .

    Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   84 / 91
Surrogate Encoding
definicja




      Każdy bajt ∈ [0x80; 0xff] zamieniany jest na znak unicode
      ∈ [U + DC80; U + DCFF]
      Przykład:
      ”jalapexf1o.txt” → b”jalapeudcf1o.txt”




                                                         .   .      .      .       .    .

    Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   84 / 91
Surrogate Encoding
definicja




      Każdy bajt ∈ [0x80; 0xff] zamieniany jest na znak unicode
      ∈ [U + DC80; U + DCFF]
      Przykład:
      ”jalapexf1o.txt” → b”jalapeudcf1o.txt”
      Podobnie znaki unicode ∈ [U + DC80; U + DCFF] są zamieniane na
      bajty ∈ [0x80; 0xff] kiedy występuję w argumentach funkcji interfejsu
      systemowego




                                                         .   .      .      .       .    .

    Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   84 / 91
Surrogate Encoding
Przykład




Jeśli w wywołaniu systemowy widać znak rodzaju udcxx znaczy to że
znak nie ASCII został przesłany do interfejsu systemowego
     >>> glob.glob("*.txt")
     [ 'jalapeudcf1o.txt', 'spam.txt']
     >>> f = open("jalapeudcf1o.txt")




                                                        .   .      .      .       .    .

   Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   85 / 91
Surrogate Encoding
integracja z Unicode


      Czy Surrogate Encoding jest kompatybilne z Unicode?




                                                         .   .      .      .       .    .

    Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   86 / 91
Surrogate Encoding
integracja z Unicode


      Czy Surrogate Encoding jest kompatybilne z Unicode?
      Nie do końca




                                                         .   .      .      .       .    .

    Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   86 / 91
Surrogate Encoding
integracja z Unicode


      Czy Surrogate Encoding jest kompatybilne z Unicode?
      Nie do końca
      Poprawny unicode nie zawiera znaków ∈ [U + DC80; U + DCFF]




                                                         .   .      .      .       .    .

    Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   86 / 91
Surrogate Encoding
integracja z Unicode


      Czy Surrogate Encoding jest kompatybilne z Unicode?
      Nie do końca
      Poprawny unicode nie zawiera znaków ∈ [U + DC80; U + DCFF]
      na przykład używanie napisów z surrogate encoding powoduje wyjątki
      w funkcji print()
             >>> files = glob.glob("*.txt")
             >>> files
             [ 'jalapeudcf1o.txt', 'spam.txt']
             >>> for name in files:
             print(name)
             ...
             Traceback (most recent call last):
             File "<stdin>", line 1, in <module>
             UnicodeEncodeError: 'utf-8' codec can't␣encode␣character
             'udcf1'␣in␣position␣6:␣surrogates␣not␣allowed

                                                          .   .      .      .       .    .

    Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   86 / 91
Surrogate Encoding
Implementacja




     Surrogate encoding zaimplementowane jest jako error handler dla
     metod encode(), decode() - patrz help(encode)
            >>> s = b"jalapexf1o.txt"
            >>> t = s.decode('utf-8','surrogateescape')
            >>> t
            'jalapeudcf1o.txt'
            >>> t.encode('utf-8','surrogateescape')
            b'jalapexf1o.txt'




                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   87 / 91
Surrogate Encoding
Implementacja




     Surrogate encoding zaimplementowane jest jako error handler dla
     metod encode(), decode() - patrz help(encode)
            >>> s = b"jalapexf1o.txt"
            >>> t = s.decode('utf-8','surrogateescape')
            >>> t
            'jalapeudcf1o.txt'
            >>> t.encode('utf-8','surrogateescape')
            b'jalapexf1o.txt'

     Jeśli rozważamy pisanie kodu, który ma do czynienia z interfejsem
     systemowy, i chcemy żeby kod był przenośny, wtedy będziemy
     potrzebować powyższych rozwiązań.


                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   87 / 91
Table of Contents

1.   Wstęp

2.   Python 3

3.   Tekst

4.   Formatowanie tesktu

5.   Dane binarne

6.   Moduł I/O

7.   System Interface

8.   Projektowanie bibliotek

                                                          .   .      .      .       .    .

     Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   88 / 91
Unicode i Bytes a biblioteki




    W Pyhon2 mogliśmy pomijać różnice między tekstem a ciągiem
    bajtów. Wiele bibliotek pomijało tą sprawę (moduły sieciowe, moduły
    przetwarzania danych …)




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   89 / 91
Unicode i Bytes a biblioteki




    W Pyhon2 mogliśmy pomijać różnice między tekstem a ciągiem
    bajtów. Wiele bibliotek pomijało tą sprawę (moduły sieciowe, moduły
    przetwarzania danych …)
    Python3 traktuje tą sprawę poważnie i musimy być precyzyjni w
    obsłudze I/O




                                                       .   .      .      .       .    .

  Robert Zaremba (Scale it)   Python Zaawansowane IO       Wrocław 2011 listopad 10   89 / 91
Unicode i Bytes a biblioteki
Przykład




     Niepoprawna funkcja:
            def send_response(s,code,msg):
                s.sendall("HTTP/1.0␣%s␣%srn" % (code,msg))
                send_response(s,"200","OK")




                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   90 / 91
Unicode i Bytes a biblioteki
Przykład




     Niepoprawna funkcja:
            def send_response(s,code,msg):
                s.sendall("HTTP/1.0␣%s␣%srn" % (code,msg))
                send_response(s,"200","OK")

     Funkcja jest niepoprawna ponieważ socket operuje tylko na danych
     binarnych (bytes, bytearray).
     Czyli nie możemy wysyłać tekstu (np: ”‘Hello!”’)




                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   90 / 91
Unicode i Bytes a biblioteki
Przykład




     W Python3 trzeba podać dokładnie kodowanie tekstu:
            def send_response(s,code,msg):
                resp = "HTTP/1.0␣%s␣%srn" % (code,msg)
                s.sendall(resp.encode('ascii'))
                send_response(s,"200","OK")




                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   91 / 91
Unicode i Bytes a biblioteki
Przykład




     W Python3 trzeba podać dokładnie kodowanie tekstu:
            def send_response(s,code,msg):
                resp = "HTTP/1.0␣%s␣%srn" % (code,msg)
                s.sendall(resp.encode('ascii'))
                send_response(s,"200","OK")

     Zasady wysyłania danych:




                                                         .   .      .      .       .    .

   Robert Zaremba (Scale it)    Python Zaawansowane IO       Wrocław 2011 listopad 10   91 / 91
Unicode i Bytes a biblioteki
Przykład




     W Python3 trzeba podać dokładnie kodowanie tekstu:
            def send_response(s,code,msg):
                resp = "HTTP/1.0␣%s␣%srn" % (code,msg)
                s.sendall(resp.encode('ascii'))
                send_response(s,"200","OK")

     Zasady wysyłania danych:
             Każdy tekst wysyłany musi być najpierw kodowany do bytes




                                                          .   .      .      .       .    .

   Robert Zaremba (Scale it)     Python Zaawansowane IO       Wrocław 2011 listopad 10   91 / 91
Unicode i Bytes a biblioteki
Przykład




     W Python3 trzeba podać dokładnie kodowanie tekstu:
            def send_response(s,code,msg):
                resp = "HTTP/1.0␣%s␣%srn" % (code,msg)
                s.sendall(resp.encode('ascii'))
                send_response(s,"200","OK")

     Zasady wysyłania danych:
             Każdy tekst wysyłany musi być najpierw kodowany do bytes
             Każdy tekst odbierany musi być najpierw dekodowany do unicode (jeśli
             chcemy nim operować jako tekst)




                                                           .   .      .      .       .    .

   Robert Zaremba (Scale it)      Python Zaawansowane IO       Wrocław 2011 listopad 10   91 / 91

Contenu connexe

Similaire à Python IO

Let's Go! - wprowadzenie do Go
Let's Go!  - wprowadzenie do GoLet's Go!  - wprowadzenie do Go
Let's Go! - wprowadzenie do GoRafal Piekarski
 
Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010Natalia Stanko
 
PLNOG 8: Paweł Białasiewicz - Rozwiązywanie problemów sieciowych za pomocą sn...
PLNOG 8: Paweł Białasiewicz - Rozwiązywanie problemów sieciowych za pomocą sn...PLNOG 8: Paweł Białasiewicz - Rozwiązywanie problemów sieciowych za pomocą sn...
PLNOG 8: Paweł Białasiewicz - Rozwiązywanie problemów sieciowych za pomocą sn...PROIDEA
 
Open Xml Translator - czyli o oswajaniu formatow
Open Xml Translator - czyli o oswajaniu formatowOpen Xml Translator - czyli o oswajaniu formatow
Open Xml Translator - czyli o oswajaniu formatow3camp
 
PLNOG 3: Janusz Dziemidowicz - Integracja komunikatora opartego o protokół X...
PLNOG 3: Janusz Dziemidowicz -  Integracja komunikatora opartego o protokół X...PLNOG 3: Janusz Dziemidowicz -  Integracja komunikatora opartego o protokół X...
PLNOG 3: Janusz Dziemidowicz - Integracja komunikatora opartego o protokół X...PROIDEA
 
Jak stworzyć wysokowydajny i skalowalny stos sieciowy dla 72 rdzeni CPU?
Jak stworzyć wysokowydajny i skalowalny stos sieciowy dla 72 rdzeni CPU?Jak stworzyć wysokowydajny i skalowalny stos sieciowy dla 72 rdzeni CPU?
Jak stworzyć wysokowydajny i skalowalny stos sieciowy dla 72 rdzeni CPU?Semihalf
 

Similaire à Python IO (11)

Let's Go! - wprowadzenie do Go
Let's Go!  - wprowadzenie do GoLet's Go!  - wprowadzenie do Go
Let's Go! - wprowadzenie do Go
 
Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010
 
Python. Od podstaw
Python. Od podstawPython. Od podstaw
Python. Od podstaw
 
Jak działa CPython
Jak działa CPythonJak działa CPython
Jak działa CPython
 
PLNOG 8: Paweł Białasiewicz - Rozwiązywanie problemów sieciowych za pomocą sn...
PLNOG 8: Paweł Białasiewicz - Rozwiązywanie problemów sieciowych za pomocą sn...PLNOG 8: Paweł Białasiewicz - Rozwiązywanie problemów sieciowych za pomocą sn...
PLNOG 8: Paweł Białasiewicz - Rozwiązywanie problemów sieciowych za pomocą sn...
 
Open Xml Translator - czyli o oswajaniu formatow
Open Xml Translator - czyli o oswajaniu formatowOpen Xml Translator - czyli o oswajaniu formatow
Open Xml Translator - czyli o oswajaniu formatow
 
Ubuntu server
Ubuntu serverUbuntu server
Ubuntu server
 
PLNOG 3: Janusz Dziemidowicz - Integracja komunikatora opartego o protokół X...
PLNOG 3: Janusz Dziemidowicz -  Integracja komunikatora opartego o protokół X...PLNOG 3: Janusz Dziemidowicz -  Integracja komunikatora opartego o protokół X...
PLNOG 3: Janusz Dziemidowicz - Integracja komunikatora opartego o protokół X...
 
Jak stworzyć wysokowydajny i skalowalny stos sieciowy dla 72 rdzeni CPU?
Jak stworzyć wysokowydajny i skalowalny stos sieciowy dla 72 rdzeni CPU?Jak stworzyć wysokowydajny i skalowalny stos sieciowy dla 72 rdzeni CPU?
Jak stworzyć wysokowydajny i skalowalny stos sieciowy dla 72 rdzeni CPU?
 
DSL - DYI
DSL - DYIDSL - DYI
DSL - DYI
 
Iron Python I Dlr
Iron Python I DlrIron Python I Dlr
Iron Python I Dlr
 

Python IO

  • 1. . Python Zaawansowane IO przetwarzanie tekstu, input, output . Robert Zaremba Scale it Wrocław 2011 listopad 10 . . . . . .
  • 2. Table of Contents 1. Wstęp 2. Python 3 3. Tekst 4. Formatowanie tesktu 5. Dane binarne 6. Moduł I/O 7. System Interface 8. Projektowanie bibliotek . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 2 / 91
  • 3. Po co tekst i I/O Większość programów komunikują się ze światem za pomocą czytelnego tekstu. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 3 / 91
  • 4. Po co tekst i I/O Większość programów komunikują się ze światem za pomocą czytelnego tekstu. odczytują i zapisują tekst z pliku odczytują i zapisują tekst do bazy danych odbierają i wysyłają po tekst po sieci. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 3 / 91
  • 5. Po co tekst i I/O Większość programów komunikują się ze światem za pomocą czytelnego tekstu. odczytują i zapisują tekst z pliku odczytują i zapisują tekst do bazy danych odbierają i wysyłają po tekst po sieci. I/O jest “corem” tego do czego używamy Pythona (skrypty, przetwarzanie danych, sklejanie programów ...) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 3 / 91
  • 6. Po co tekst i I/O Większość programów komunikują się ze światem za pomocą czytelnego tekstu. odczytują i zapisują tekst z pliku odczytują i zapisują tekst do bazy danych odbierają i wysyłają po tekst po sieci. I/O jest “corem” tego do czego używamy Pythona (skrypty, przetwarzanie danych, sklejanie programów ...) Co się pojawiło? Python 3 . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 3 / 91
  • 7. Python 3 W Python 3 na nowo zaimplementowano biblioteki powiązane z I/O. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 4 / 91
  • 8. Python 3 W Python 3 na nowo zaimplementowano biblioteki powiązane z I/O. Mamy nowe typy danych . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 4 / 91
  • 9. Python 3 W Python 3 na nowo zaimplementowano biblioteki powiązane z I/O. Mamy nowe typy danych Python 3 dostarcza wprowadza w ogóle dużo zmian (nowe biblioteki, część starych bibliotek pod nowymi nazwami - eg urllib …) Większość starego kodu (z Pythona 2) da się przenieść do Pythona 3 za pomocą narzędzia 2to3 . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 4 / 91
  • 10. Python 3 W Python 3 na nowo zaimplementowano biblioteki powiązane z I/O. Mamy nowe typy danych Python 3 dostarcza wprowadza w ogóle dużo zmian (nowe biblioteki, część starych bibliotek pod nowymi nazwami - eg urllib …) Większość starego kodu (z Pythona 2) da się przenieść do Pythona 3 za pomocą narzędzia 2to3 Ale nie operacje I/O . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 4 / 91
  • 11. Pojęcia str vs unicode . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 5 / 91
  • 12. Pojęcia str vs unicode print statement (i domyślne użycie __str__() metody call) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 5 / 91
  • 13. Pojęcia str vs unicode print statement (i domyślne użycie __str__() metody call) metody dostępu do plików . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 5 / 91
  • 14. Pojęcia str vs unicode print statement (i domyślne użycie __str__() metody call) metody dostępu do plików std . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 5 / 91
  • 15. Table of Contents 1. Wstęp 2. Python 3 3. Tekst 4. Formatowanie tesktu 5. Dane binarne 6. Moduł I/O 7. System Interface 8. Projektowanie bibliotek . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 6 / 91
  • 16. Python 3 składnia print . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 7 / 91
  • 17. Python 3 składnia print wyjątki: try: ... except Exception as e: # "as" wymagane ... . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 7 / 91
  • 18. Python 3 built-ins zmieniono wiele wbudowanych operatorów range tworzą teraz generator, a nie listy wiele kolekcji zwracają iteratory zamiast list ogólnie Python 3 preferuje iteratory / generatory . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 8 / 91
  • 19. Python 3 Porządek w bibliotece Python2: urllib, urllib2 - dwie biblioteki? gdzie co jest i po co? from urllib2 import urlopen u = urlopen("http://www.example.com") Queue, SocketServer anydbm, dbhash, dbm, dumbdbm, gdbm ... Python3 urllib - jedna biblioteka z poukładaną funkcjonalnością from urllib.request import urlopen u = urlopen("http://www.example.com") queue, socketserver dbm.{anydbm, dbhash, dbm, dumbdbm, gdbm ...} . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 9 / 91
  • 20. Python 3 2to3 Przykładowy kod dla Python2.7 # printlinks.py import urllib import sys from HTMLParser import HTMLParser class LinkPrinter(HTMLParser): def handle_starttag(self,tag,attrs): if tag == 'a': for name,value in attrs: if name == 'href': print value data = urllib.urlopen(sys.argv[1]).read() LinkPrinter().feed(data) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 10 / 91
  • 21. Python 3 2to3 użycie narzędzia 2to3. Pokazuje co i jak zamienić bash % 2to3 printlinks.py ... --- printlinks.py (original) +++ printlinks.py (refactored) @@ -1,12 +1,12 @@ -import urllib +import urllib.request, urllib.parse, urllib.error -from HTMLParser import HTMLParser +from html.parser import HTMLParser -if name == 'href': print value +if name == 'href': print(value) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 11 / 91
  • 22. Python 3 2to3 użycie narzędzia 2to3. Pokazuje co i jak zamienić bash % 2to3 printlinks.py ... --- printlinks.py (original) +++ printlinks.py (refactored) @@ -1,12 +1,12 @@ -import urllib +import urllib.request, urllib.parse, urllib.error -from HTMLParser import HTMLParser +from html.parser import HTMLParser -if name == 'href': print value +if name == 'href': print(value) Ale dalej nie działa, czemu? . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 11 / 91
  • 23. Python 3 2to3 bash % python3 printlinks.py http://www.python.org Traceback (most recent call last): File "printlinks.py", line 12, in <module> LinkPrinter().feed(data) File "/Users/beazley/Software/lib/python3.1/html/parser.py", line 107, in feed self.rawdata = self.rawdata + data TypeError: Can't␣convert␣'bytes'␣object␣to␣str␣implicitly Jak widzimy błąd jest w obsłudze napisów. 2to3 nie może zgadnąć o jakie napisy nam chodzi . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 12 / 91
  • 24. Python 3 2to3 bash % python3 printlinks.py http://www.python.org Traceback (most recent call last): File "printlinks.py", line 12, in <module> LinkPrinter().feed(data) File "/Users/beazley/Software/lib/python3.1/html/parser.py", line 107, in feed self.rawdata = self.rawdata + data TypeError: Can't␣convert␣'bytes'␣object␣to␣str␣implicitly Jak widzimy błąd jest w obsłudze napisów. 2to3 nie może zgadnąć o jakie napisy nam chodzi Fix: LinkPrinter().feed(data.decode(′ utf − 8′ )) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 12 / 91
  • 25. Python 3 I/O Po co to wszytko? Wiele “prawdziwych” programów polegają na I/O . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 13 / 91
  • 26. Table of Contents 1. Wstęp 2. Python 3 3. Tekst 4. Formatowanie tesktu 5. Dane binarne 6. Moduł I/O 7. System Interface 8. Projektowanie bibliotek . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 14 / 91
  • 27. Tekst Problemy kodowanie - koszmar Zależności między bibliotekami biblioteki operują na stringach trzeba konfigurować klasy aby wiedziały jak stringi są kodowane znak → ile bajtów go koduje? tłumaczenie tekstów niektóre biblioteki nie obsługują wielu kodowań automatycznie trzeba samemu przekodowywać tekst wczytywanie plików. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 15 / 91
  • 28. Tekst Problemy kodowanie - koszmar Zależności między bibliotekami biblioteki operują na stringach trzeba konfigurować klasy aby wiedziały jak stringi są kodowane znak → ile bajtów go koduje? tłumaczenie tekstów niektóre biblioteki nie obsługują wielu kodowań automatycznie trzeba samemu przekodowywać tekst wczytywanie plików. Python ma być w prosty i intuicyjny . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 15 / 91
  • 29. Tekst co poukładano W Python 3 tekst jest unicode przetwarzanie tekstu także odbywa się na podstawie unicode . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 16 / 91
  • 30. Tekst Unicode każdy znak ma swój unikalny kod (w lokalne kodowania są przystosowane do lokalnych alfabetów) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 17 / 91
  • 31. Tekst Unicode każdy znak ma swój unikalny kod (w lokalne kodowania są przystosowane do lokalnych alfabetów) większa “pojemność znaku” tekst więcej zajmuje :( . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 17 / 91
  • 32. Tekst Unicode każdy znak ma swój unikalny kod (w lokalne kodowania są przystosowane do lokalnych alfabetów) większa “pojemność znaku” tekst więcej zajmuje :( ) największy numer znaku: U+10FFF http://www.unicode.org/charts . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 17 / 91
  • 33. Tekst Unicode każdy znak ma swój unikalny kod (w lokalne kodowania są przystosowane do lokalnych alfabetów) większa “pojemność znaku” tekst więcej zajmuje :( ) największy numer znaku: U+10FFF http://www.unicode.org/charts unicode literals: "xf1" # standard ascii 'ñ' "u2191": # ↑ "U0001d122" . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 17 / 91
  • 34. Tekst testy z konsolą testowanie znaków w python2 i python3 methody repr, ascii, chr ascii('ś') # nowa metoda w python3 repr('ś') chr(0x15b) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 18 / 91
  • 35. Tekst Unicode Unicod jest przechowywany jako “C” int sprawdzenie: >>> sys.maxunicode 65535 # 16-bits >>> sys.maxunicode 1114111 # 32-bits . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 19 / 91
  • 36. Tekst Unicode Tekst w Python3 zajmuje 2 lub 4 razy więcej niż w Python2 z tego powodu operacje na tekście wykonują się dłużej: praca z konsolą timeit("text[:-1]","text='x'*100000") timeit("text.upper()","text='x'*1000") . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 20 / 91
  • 37. Tekst Unicode - zalety Bez względu na kodowanie tekstu w pliku, w pythonie dany tekst jest zawsze tak samo reprezentowany (jako unicode) Biblioteki nie muszą martwić się o kodowanie użytkownik nie musi martwić się komunikację z bibliotekami i wyświetlanie . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 21 / 91
  • 38. Tekst Unicode - zalety Bez względu na kodowanie tekstu w pliku, w pythonie dany tekst jest zawsze tak samo reprezentowany (jako unicode) Biblioteki nie muszą martwić się o kodowanie użytkownik nie musi martwić się komunikację z bibliotekami i wyświetlanie przy czytaniu strumienia od razu musimy zadeklarować kodowanie → mniej błędów Wbudowana funkcja open() przyjmuje teraz argument encoding z domyślną wartością "utf-8" w pythonie 2 wszystko to było ukryte, co mogło powodować błędy w przyszłości . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 21 / 91
  • 39. Tekst Unicode - konsekwencje unicode to wewnętrzna struktura pythona inne programy mogą jej nie rozumieć Aby przesyłać unicode trzeba używać metod encode, decode >>> s = "Jalapeño" >>> data = s.encode('utf-8') >>> data b'Jalapexc3xb1o' >>> data.decode('utf-8') 'Jalapeño' . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 22 / 91
  • 40. Tekst Unicode - Python3, podsumowanie Python3 używa unicode do reprezentacji “stringów” unicode to inty Jeśli nie zaznaczysz inaczej, każdy unicode będzie zakładał kodowanie UTF-8 strumienie bajtów to (bytes) bytes nie “zna” kodowań bytes to ciągi bajtów byets wspiera operacje na ciągach (teracja, slices...) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 23 / 91
  • 41. Tekst Unicode - błędy na jakie można się natrafić Błąd używania złego kodowania >>> f = open('foo',encoding='ascii') >>> data = f.read() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python3.2/encodings/ ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors) [0] UnicodeDecodeError: 'ascii' codec can't␣decode␣byte 0xc3␣in␣position␣6:␣ordinal␣not␣in␣range(128) >>> >>>␣f␣=␣open('foo',encoding='utf-8') >>>␣data␣=␣f.read() . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 24 / 91
  • 42. Tekst Uwagi unicode to potężny standard. Niektóre znaki są prezentowane jako różne kody >>> s = "Jalapexf1o" >>> t = "Jalapenu0303o" # 'n' + ' ' >>> s 'Jalapeño' >>> t 'Jalapeño' >>> s == t False >>> len(s), len(t) (8, 9) mimo to tekst powinien być jednoznaczny - jako że kody klawiatury są ustandaryzowane. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 25 / 91
  • 43. Table of Contents 1. Wstęp 2. Python 3 3. Tekst 4. Formatowanie tesktu 5. Dane binarne 6. Moduł I/O 7. System Interface 8. Projektowanie bibliotek . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 26 / 91
  • 44. Print nowe użycie definiowanie separatora >>> print(1,2,3,sep=':') 1:2:3 # python2 >>> print("Hello","World",sep='') HelloWorld definiowanie końca linii >>> print("What?",end="!?!n") What?!?! Pytanie: jak w python2 wydrukować coś na ekran bez znaku nowej linii na końcu . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 27 / 91
  • 45. Print nowe użycie definiowanie separatora >>> print(1,2,3,sep=':') 1:2:3 # python2 >>> print("Hello","World",sep='') HelloWorld definiowanie końca linii >>> print("What?",end="!?!n") What?!?! Pytanie: jak w python2 wydrukować coś na ekran bez znaku nowej linii na końcu >>> sys.stdout.write() . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 27 / 91
  • 46. Formatowanie tekstu python2 s = "%10.2f" % price python3 s = format(price,"10.2f") . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 28 / 91
  • 47. Formatowanie tekstu funkcje str, repr, format funkcje str, repr, format wywołują odpowiednio metody obiektu: __str__, __repr__, __format__ . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 29 / 91
  • 48. Formatowanie tekstu funkcje str, repr, format funkcje str, repr, format wywołują odpowiednio metody obiektu: __str__, __repr__, __format__ format bierze dodatkowy argument - “code formaters”, analogiczny do % z python2 >>> x = 1/3 >>> format(x,"0.4f") '0.3333' >>> format(x,"20.2f") '␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣0.33' . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 29 / 91
  • 49. Formatowanie tekstu code formaters “code formaters” ”d” - decimal integer ”f” - floating point ”s” - stringach ”e” - notacja wykładnicza ”x” - hexadecimal ”o” - octal ”b” - binary ”%” - procentowa wartość . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 30 / 91
  • 50. Formatowanie tekstu code formaters modyfikatory precyzji i wyrównania: [fill][<|>|^][width][thousands sep][.precision]code . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 31 / 91
  • 51. Formatowanie tekstu code formaters modyfikatory precyzji i wyrównania: [fill][<|>|^][width][thousands sep][.precision]code [fill] [znak wypełnienia, domyślnie “ ”] [<|>|^] [do lewej| do prawej| centruj ] [width] [szerokość] [thousands sep] [separator tysięcznych części liczby] [.precision]code [.ilość cyfr znaczących] typ kodu . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 31 / 91
  • 52. Formatowanie tekstu code formaters >>> format(1/2., "0.3f") '0.500' >>> format(1/2., "5.3") '␣␣0.5' >>> format(1/2., "^5") '␣0.5␣' >>> format(1/2., "=^5") '=0.5=' >>> format(1e8., ",.0") '1+e08' >>> format(1e8., ",.0f") '100,000,000' >>> format(1e8., ",") '100,000,000.0' . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 32 / 91
  • 53. Formatowanie tekstu code formaters metodę __format__(self, fmt) można nadpisać. Wtedy sami możemy interpretować “code formaters” oraz dodawać swoje kody. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 33 / 91
  • 54. Formatowanie tekstu string format Metoda format dla napisów pozwala na tworzenie “koszyków” w tekście. Koszyki później są zastępowane odpowiednimi wartościami. Koszyki te mogą zawiertać formatery i argumenty: pozycyjne "{0}␣has␣{1}␣messages".format("Dave",37) pozycyjne "{name}␣has␣{n}␣messages".format(name="Dave",n=37) pozycyjne "{}␣has␣{}␣messages".format("Dave",37) indeksowe record = {'name' : 'Dave', 'n' : 37} '{r[name]}␣has␣{r[n]}␣messages'.format(r=record) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 34 / 91
  • 55. Formatowanie tekstu string format Jak tworzona jest wartość obiektu który “wkładamy” do koszyka formatera? {item} # Replaced by str(item) {item!r} # Replaced by repr(item) {item:fmt} # Replaced by format(item, fmt) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 35 / 91
  • 56. Formatowanie tekstu string format Jak tworzona jest wartość obiektu który “wkładamy” do koszyka formatera? {item} # Replaced by str(item) {item!r} # Replaced by repr(item) {item:fmt} # Replaced by format(item, fmt) foramt pozwala na pojedyncze zagnieżdżenie {} >>> s = ('ACME',50,91.10) >>> "{0:{width}s}␣{2:{width}.2f}".format(*s,width=12) 'ACME␣␣␣␣␣␣␣␣91.10' . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 35 / 91
  • 57. Formatowanie tekstu string format Jak stworzyć znak ’{’ w formaterze? Trzeba użyć ’{{’ . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 36 / 91
  • 58. Formatowanie tekstu format_map Metoda format może korzystać z nazwanych argumentów podczas formatowania tekstu. Jeśli już mamy słownik i nie chcemy nadmiernie tworzyć ekspansji słownika, możemy skorzystać z metody format_map, która oczekuje słownika, a nie listy argumentów. "{name}␣has␣{n}␣messages".format_map({ 'name': 'Robert' 'n': 'Hello' }) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 37 / 91
  • 59. Szablony tekstu string.Templates Podobną funkcjonalność do formatowania napisów daje klasa string.Template: from string import Template msg = Template("namehasn messages") print(msg.substitute(name="Dave",n=37) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 38 / 91
  • 60. Table of Contents 1. Wstęp 2. Python 3 3. Tekst 4. Formatowanie tesktu 5. Dane binarne 6. Moduł I/O 7. System Interface 8. Projektowanie bibliotek . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 39 / 91
  • 61. Bytes definiowanie Definiowanie “bytes” a = b"ACME␣50␣91.10" # Byte string literal b = bytes([1,2,3,4,5]) # From a list of integers c = bytes(10) # An array of 10 zero-bytes d = bytes("Jalapeño","utf-8") # Encoded from string . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 40 / 91
  • 62. Bytes definiowanie Definiowanie “bytes” a = b"ACME␣50␣91.10" # Byte string literal b = bytes([1,2,3,4,5]) # From a list of integers c = bytes(10) # An array of 10 zero-bytes d = bytes("Jalapeño","utf-8") # Encoded from string Tworzenie z stringu zawierającego liczbę hexadecimal e = bytes.fromhex("48656c6c6f") . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 40 / 91
  • 63. Bytes właściwości Bytes posiada standardowe metody napisów >>> s = b"ACME␣50␣91.10" >>> s.split() [b'ACME', b'50', b'91.10'] >>> s.lower() b'acme␣50␣91.10' >>> s[5:7] b'50' . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 41 / 91
  • 64. Bytes właściwości Bytes posiada standardowe metody napisów >>> s = b"ACME␣50␣91.10" >>> s.split() [b'ACME', b'50', b'91.10'] >>> s.lower() b'acme␣50␣91.10' >>> s[5:7] b'50' Bytes tak samo jak napisy są niemutowalne . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 41 / 91
  • 65. Bytes właściwości bytes to tablica int-ów >>> s = b"ACME␣50␣91.10" >>> s[0] 65 >>> s[1] 67 . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 42 / 91
  • 66. Bytes właściwości bytes to tablica int-ów >>> s = b"ACME␣50␣91.10" >>> s[0] 65 >>> s[1] 67 bytes to standardowa struktura operacji I/O . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 42 / 91
  • 67. Bytes Problemy Portowanie kodu z Python2 do Python3 data = s.recv(1024) if data[0] == b'+': # ERROR! ... # fix data = s.recv(1024) if data[0] == 0x2b: # CORRECT ... . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 43 / 91
  • 68. Bytes Portowanie Nie potrzeba używać metody ord . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 44 / 91
  • 69. Bytes Portowanie Nie potrzeba używać metody ord konwersja obiektów do “bytes” - postać binarna obiektów: >>> x = 7 >>> bytes(x) b'x00x00x00x00x00x00x00' >>> str(x).encode('ascii') b'7' . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 44 / 91
  • 70. bytearray bytearray to mutowalne “bytes” >>> s = bytearray(b"ACME␣50␣91.10") >>> s[:4] = b"PYTHON" >>> s bytearray(b"PYTHON␣50␣91.10") >>> s[0] = 0x70 # Must assign integers >>> s bytearray(b'pYTHON␣50␣91.10") . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 45 / 91
  • 71. bytearray bytearray to mutowalne “bytes” >>> s = bytearray(b"ACME␣50␣91.10") >>> s[:4] = b"PYTHON" >>> s bytearray(b"PYTHON␣50␣91.10") >>> s[0] = 0x70 # Must assign integers >>> s bytearray(b'pYTHON␣50␣91.10") zawiera wiele operacji “listowych” >>> s.append(23) >>> s.append(45) >>> s.extend([1,2,3,4]) >>> s bytearray(b'ACME␣50␣91.10x17-x01x02x03x04') . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 45 / 91
  • 72. Bytes a Unicode bytes nie służy do przetwarzania tekstu . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 46 / 91
  • 73. Bytes a Unicode bytes nie służy do przetwarzania tekstu można użyć ich do tekstu - grozi to strasznym problemom (s[1] to nie litera, a część kodu litery) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 46 / 91
  • 74. Bytes a Unicode bytes nie służy do przetwarzania tekstu można użyć ich do tekstu - grozi to strasznym problemom (s[1] to nie litera, a część kodu litery) Python3 jasno oddziela tekst od ciągu bajtów (unicode vs bytes) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 46 / 91
  • 75. Bytes a Unicode bytes nie służy do przetwarzania tekstu można użyć ich do tekstu - grozi to strasznym problemom (s[1] to nie litera, a część kodu litery) Python3 jasno oddziela tekst od ciągu bajtów (unicode vs bytes) >>> s = b"ACME␣50␣91.10" >>> 'ACME' in s Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Type str doesn't␣support␣the␣buffer␣API . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 46 / 91
  • 76. Bytes a Unicode bytes nie służy do przetwarzania tekstu można użyć ich do tekstu - grozi to strasznym problemom (s[1] to nie litera, a część kodu litery) Python3 jasno oddziela tekst od ciągu bajtów (unicode vs bytes) >>> s = b"ACME␣50␣91.10" >>> 'ACME' in s Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Type str doesn't␣support␣the␣buffer␣API print() powiniena być tylko używana z tekstem (unicode) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 46 / 91
  • 77. Bytes a Unicode bytes nie służy do przetwarzania tekstu można użyć ich do tekstu - grozi to strasznym problemom (s[1] to nie litera, a część kodu litery) Python3 jasno oddziela tekst od ciągu bajtów (unicode vs bytes) >>> s = b"ACME␣50␣91.10" >>> 'ACME' in s Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Type str doesn't␣support␣the␣buffer␣API print() powiniena być tylko używana z tekstem (unicode) Bytes nie wspierają metody format . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 46 / 91
  • 78. Bytes a Unicode bytes nie służy do przetwarzania tekstu można użyć ich do tekstu - grozi to strasznym problemom (s[1] to nie litera, a część kodu litery) Python3 jasno oddziela tekst od ciągu bajtów (unicode vs bytes) >>> s = b"ACME␣50␣91.10" >>> 'ACME' in s Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Type str doesn't␣support␣the␣buffer␣API print() powiniena być tylko używana z tekstem (unicode) Bytes nie wspierają metody format Wiele funkcji operujących na tekście nie akcepują bytes (np: time.strptime) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 46 / 91
  • 79. Gdzie używać bytes bytes nadają się do niskopoziomowych operacji I/O. (przekazywanie wiadomości, systemy wbudowane, obliczenia rozproszone …) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 47 / 91
  • 80. Użycie bytes konkatenacja ciągu w Python2 chunks = [] while True: chunk = s.recv(BUFSIZE) if not chunk: break chunks.append(chunk) msg = b"".join(chunks) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 48 / 91
  • 81. Użycie bytes konkatenacja ciągu w Python2 chunks = [] while True: chunk = s.recv(BUFSIZE) if not chunk: break chunks.append(chunk) msg = b"".join(chunks) konkatenacja ciągu w Python3 msg = bytearray() while True: chunk = s.recv(BUFSIZE) if not chunk: break msg.extend(chunk) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 48 / 91
  • 82. Użycie bytes konkatenacja ciągu w Python2 chunks = [] while True: chunk = s.recv(BUFSIZE) if not chunk: break chunks.append(chunk) msg = b"".join(chunks) konkatenacja ciągu w Python3 msg = bytearray() while True: chunk = s.recv(BUFSIZE) if not chunk: break msg.extend(chunk) wielka wydajność operacji na bytes i bytearray . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 48 / 91
  • 83. Użycie bytes przekazywanie wiadomości Przekazywanie wiadomości. objs = [ ... ] # List of tuples to pack msg = bytearray() # Empty message # First pack the number of objects msg.extend(struct.pack("<I",len(objs))) for x in objs: # Incrementally pack each object msg.extend(struct.pack(fmt, *x)) f.write(msg) # Do something with the message . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 49 / 91
  • 84. Użycie bytes XOR - cipher kodowanie XOR >>> s = b"Hello␣World" >>> t = bytes(x^42 for x in s) >>> t b'bOFFEn}EXFN' >>> bytes(x^42 for x in t) b'Hello␣World' . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 50 / 91
  • 85. Użycie bytes suma kontrolna dołączanie sumy kontrolnej chk = 0 for n in msg: chk ^= n msg.append(chk) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 51 / 91
  • 86. Bufory podobieństwa bytearray buffers bufor to ciągły obszar pamięci bufferarray() jest przykładem buforu . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 52 / 91
  • 87. Bufory podobieństwa bytearray buffers bufor to ciągły obszar pamięci bufferarray() jest przykładem buforu przykład: array.array("i", [1,2,3,4,5]) numpy.array([1,2,3,4,5]) ctypes.ARRAY(ctypes.c_int,5)(1,2,3,4,5) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 52 / 91
  • 88. Bufory podobieństwa bytearray buffers bufor to ciągły obszar pamięci bufferarray() jest przykładem buforu przykład: array.array("i", [1,2,3,4,5]) numpy.array([1,2,3,4,5]) ctypes.ARRAY(ctypes.c_int,5)(1,2,3,4,5) można powiedzieć że powyższe struktury są zamienne z typem bytes . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 52 / 91
  • 89. Memory View memoryview to “nakładka na bufor” - patrz help() >>> a = bytearray(b'Hello␣World') >>> b = memoryview(a) >>> b <memory at 0x1007014d0> >>> b[-5:] = b'There' >>> a bytearray(b'Hello␣There') . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 53 / 91
  • 90. Memory View memoryview to “nakładka na bufor” - patrz help() >>> a = bytearray(b'Hello␣World') >>> b = memoryview(a) >>> b <memory at 0x1007014d0> >>> b[-5:] = b'There' >>> a bytearray(b'Hello␣There') jest bardzo niskopoziomową strukturą . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 53 / 91
  • 91. Table of Contents 1. Wstęp 2. Python 3 3. Tekst 4. Formatowanie tesktu 5. Dane binarne 6. Moduł I/O 7. System Interface 8. Projektowanie bibliotek . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 54 / 91
  • 92. implementacja I/O w Pytonie2 I/O jest oparte o c I/O python “file” to tylko cienka nakładka na C “FILE” . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 55 / 91
  • 93. implementacja I/O w Pytonie2 I/O jest oparte o c I/O python “file” to tylko cienka nakładka na C “FILE” Python3 wprowadza swoją strukturę jak było już powiedziane Python3 przeimplementował system I/O . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 55 / 91
  • 94. funkcja open() użycie podobnie jak wcześniej obiekt zwracany przez open różni się w zależności o ustawionego argumentu file mode . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 56 / 91
  • 95. funkcja open() użycie podobnie jak wcześniej obiekt zwracany przez open różni się w zależności o ustawionego argumentu file mode przykład poniżej >>> open("foo.txt","rt") <_io.TextIOWrapper name='foo.txt' encoding='UTF-8'> >>> open("foo.txt","rb") <_io.BufferedReader name='foo.txt'> >>> open("foo.txt","rb",buffering=0) <_io.FileIO name='foo.txt' mode='rb'> . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 56 / 91
  • 96. funkcja open() użycie podobnie jak wcześniej obiekt zwracany przez open różni się w zależności o ustawionego argumentu file mode przykład poniżej >>> open("foo.txt","rt") <_io.TextIOWrapper name='foo.txt' encoding='UTF-8'> >>> open("foo.txt","rb") <_io.BufferedReader name='foo.txt'> >>> open("foo.txt","rb",buffering=0) <_io.FileIO name='foo.txt' mode='rb'> task: uruchomienie tego w python2 . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 56 / 91
  • 97. Moduł I/O moduł io składa się z różny klas: FileIO BufferedReader BufferedWriter BufferedRWPair BufferedRandom TextIOWrapper BytesIO StringIO każda klasa implementuje inny rodzaj I/O każda klasa dodaje pewien zbiór właściwości . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 57 / 91
  • 98. Moduł I/O warstwy I/O otwarcie pliku powoduje kolejno tworzenie obiektów open("foo.txt", "rt") (TextIOWrapper → BufferedReader → FileIO w Javie jest podobnie . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 58 / 91
  • 99. Moduł I/O FileIO obiekt reprezentujący surowy niebuforowany obiekt binary (FileIO(name [, mode [, closefd]]) name nazwa pliku lub numer fd mode ’r’, ’w’, ’a’, ’r+’, … closefd flaga kontrolująca czy metoda close() była wywołana. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 59 / 91
  • 100. Moduł I/O FileIO obiekt reprezentujący surowy niebuforowany obiekt binary (FileIO(name [, mode [, closefd]]) name nazwa pliku lub numer fd mode ’r’, ’w’, ’a’, ’r+’, … closefd flaga kontrolująca czy metoda close() była wywołana. FileIO jest bezpośrednio zaimplemenowany na podstawie systemowych funkcji read(), write() bezpośrednio daje dostęp do niskopoziomowych wywołań systemowych na deskryptorze pliku . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 59 / 91
  • 101. Moduł I/O FileIO obiekt reprezentujący surowy niebuforowany obiekt binary (FileIO(name [, mode [, closefd]]) name nazwa pliku lub numer fd mode ’r’, ’w’, ’a’, ’r+’, … closefd flaga kontrolująca czy metoda close() była wywołana. FileIO jest bezpośrednio zaimplemenowany na podstawie systemowych funkcji read(), write() bezpośrednio daje dostęp do niskopoziomowych wywołań systemowych na deskryptorze pliku w tym: częściowy odczyt / zapis, zwracanie systemowych kodów błędów, dostęp blokowany, nieblokowany (asynchroniczny) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 59 / 91
  • 102. FileIO używanie Python2 - moduł os fd = os.open("somefile",os.O_RDONLY) data = os.read(fd,4096) os.lseek(fd,16384,os.SEEK_SET) Python3 - obiekt FileIO f = io.FileIO("somefile","r") data = f.read(4096) f.seek(16384,os.SEEK_SET) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 60 / 91
  • 103. BufferedIO klasy implementujące buforowany I/O BufferedReader(f [, buffer_size]) BufferedWriter(f [, buffer_size [, max_buffer_size]]) BufferedRWPair(f_read, f_write [, buffer_size [, max_buffer_size]]) BufferedRandom(f [, buffer_size [, max_buffer_size]]) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 61 / 91
  • 104. BufferedIO klasy implementujące buforowany I/O BufferedReader(f [, buffer_size]) BufferedWriter(f [, buffer_size [, max_buffer_size]]) BufferedRWPair(f_read, f_write [, buffer_size [, max_buffer_size]]) BufferedRandom(f [, buffer_size [, max_buffer_size]]) każda z poniższych klas jest implementacją opartą o FileIO f = io.FileIO("foo.txt") # Open the file (raw I/O) g = io.BufferedReader(f) # Put buffering around it f = io.BufferedReader(io.FileIO("foo.txt")) # Alternative . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 61 / 91
  • 105. Bufory Bufory są kontrolowane przez dwa parametry: buffer_size, max_buffer_size buffer_size - ilość danych jaką bufor może przechować zanim “opróżni się” do I/O max_buffer_size - pojemność jaką posiada bufor zanim się zablokuje (domyślnie 2x buffer_size) Aby bufor zaakceptował więcej danych, należy wcześniej go opróżnić. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 62 / 91
  • 106. Bufory operacje na buforach buffer readers: f.peek([n]) # Return up to n bytes of data without # advancing the file pointer f.read([n]) # Return n bytes of data as bytes f.read1([n]) # Read up to n bytes using a single # read() system call . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 63 / 91
  • 107. Bufory operacje na buforach buffer readers: f.peek([n]) # Return up to n bytes of data without # advancing the file pointer f.read([n]) # Return n bytes of data as bytes f.read1([n]) # Read up to n bytes using a single # read() system call buffer writers f.write(bytes) # Write bytes f.flush() # Flush output buffers . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 63 / 91
  • 108. Bufory operacje na buforach buffer readers: f.peek([n]) # Return up to n bytes of data without # advancing the file pointer f.read([n]) # Return n bytes of data as bytes f.read1([n]) # Read up to n bytes using a single # read() system call buffer writers f.write(bytes) # Write bytes f.flush() # Flush output buffers inne operacje: seek, tell, close . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 63 / 91
  • 109. UWAGA dla obiektów “pliko podobnych” Jeśli używamy obiektów “pliko podobnych” powinniśmy używać metody readl() jeśli pominiemy tą uwagę nasz program może się rozpaść jeśli inny wątek / program będzie chciał się odwołać do tego samego pliku . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 64 / 91
  • 110. TextIOWrapper obiekt implementujący text-based I/O TextIOWrapper(buffered [, encoding [, errors [, newline [, line_buffering]]]]) buffered - A buffered file object encoding - Text encoding (e.g., 'utf-8') errors - Error handling policy (e.g. 'strict') newline - '', 'n', 'r', 'rn', or None line_buffering - Flush output after each line (False) jest jedną z warstw buforowanych strumieni I/O f = io.FileIO("foo.txt") # Open the file (raw I/O) g = io.BufferedReader(f) # Put buffering around it h = io.TextIOWrapper(g,"utf-8") # Text I/O wrapper . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 65 / 91
  • 111. Text obsługa znaku nowej linii Domyślnie pliki są otwierane w trybie ”‘universal newline”’ - znaki nowej linii są mapowane do znaku n . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 66 / 91
  • 112. Text obsługa znaku nowej linii Domyślnie pliki są otwierane w trybie ”‘universal newline”’ - znaki nowej linii są mapowane do znaku n aby pozostawić oryginalny znak nowej linii, należy użyć funkcji open z dodatkowym argumentem newline='' . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 66 / 91
  • 113. Text obsługa znaku nowej linii Domyślnie pliki są otwierane w trybie ”‘universal newline”’ - znaki nowej linii są mapowane do znaku n aby pozostawić oryginalny znak nowej linii, należy użyć funkcji open z dodatkowym argumentem newline='' jeśli nie wymusimy formatu znaku nowej linii (poprzez użycie argumentu newline w funkcji open), wtedy podczas zapisu używany jest os.linesep jako znak nowej linii. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 66 / 91
  • 114. Text obsługa kodowań w Python2 aby automatycznie zdekodować zawartość pliku podczas czytania używany jest moduł codecs . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 67 / 91
  • 115. Text obsługa kodowań w Python2 aby automatycznie zdekodować zawartość pliku podczas czytania używany jest moduł codecs w Python3 nie ma potrzeby używania codecs. W pełni zastępuje go TextIOWrapper . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 67 / 91
  • 116. Text obsługa kodowań w Python2 aby automatycznie zdekodować zawartość pliku podczas czytania używany jest moduł codecs w Python3 nie ma potrzeby używania codecs. W pełni zastępuje go TextIOWrapper TextIOWrapper jest znacznie szybszy niż codecs for line in open("biglog.txt",encoding="utf-8"): # 3.8 sec pass f = codecs.open("biglog.txt",encoding="utf-8") for line in f: # 53.3 sec pass . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 67 / 91
  • 117. open() Porównanie typ obiektu zwracanego przez funkcję open zależy od parametrów. mode buffering Result any binary 0 FileIO ”rb” != 0 BufferedReader ”wb”, ”ab” != 0 BufferedWriter ”rb”, ”wb+”, ”ab+” != 0 BufferedRandom any text != 0 TextIOWrapper . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 68 / 91
  • 118. open() Porównanie typ obiektu zwracanego przez funkcję open zależy od parametrów. mode buffering Result any binary 0 FileIO ”rb” != 0 BufferedReader ”wb”, ”ab” != 0 BufferedWriter ”rb”, ”wb+”, ”ab+” != 0 BufferedRandom any text != 0 TextIOWrapper Uwaga: niektóre kombinacje są nielegalne, a ich użycie spowoduje rzucenie wyjątku (np: unbuffered text) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 68 / 91
  • 119. I/O Stack przechodzenie po stosie I/O Scenariusz: mamy plik otwarty w text-mode, ale chcemy go czytać w binary-mode. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 69 / 91
  • 120. I/O Stack przechodzenie po stosie I/O Scenariusz: mamy plik otwarty w text-mode, ale chcemy go czytać w binary-mode. warstwy wyższe zawierają warstwy niższe. Czyli do bardziej natywnych obiektów i/o możemy się dostać przez pola obiektów wyższych: TextIOWrapper .buffer ? BufferedReader .raw ? FileIO . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 69 / 91
  • 121. I/O Stack przechodzenie po stosie I/O - przykład Pisanie danych binarnych do sys.stdout. Pomysły? . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 70 / 91
  • 122. I/O Stack przechodzenie po stosie I/O - przykład Pisanie danych binarnych do sys.stdout. Pomysły? >>> import sys >>> sys.stdout.write(b"Hello␣Worldn") Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: must be str, not bytes >>> sys.stdout.buffer.write(b"Hello␣Worldn") Hello World 12 . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 70 / 91
  • 123. I/O Stack UWAGA - warstwy! Przechodzenie po warstwach może powodować błędy gdy pracujemy z objektami typu pliki. >>> import io >>> from urllib.request import urlopen >>> u = io.TextIOWrapper( urlopen("http://www.python.org"), encoding='latin1') >>> text = u.read() >>> u = io.TextIOWrapper( urlopen("http://www.python.org"), encoding='latin1') >>> line = u.readline() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'HTTPResponse' object has no attribute 'read1' . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 71 / 91
  • 124. I/O Performance odczyt odczyt 100 Mb tekstu z pliku data = open("big.txt").read() Python 2.7.1: 0.14s Python 3.2 (UCS-2, UTF-8) : 0.90s Python 3.2 (UCS-4, UTF-8) : 1.56s . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 72 / 91
  • 125. I/O Performance odczyt odczyt 100 Mb tekstu z pliku data = open("big.txt").read() Python 2.7.1: 0.14s Python 3.2 (UCS-2, UTF-8) : 0.90s Python 3.2 (UCS-4, UTF-8) : 1.56s odczyt 100 Mb danych binarnych data = open("big.bin","rb").read() Python 2.7.1 : 0.16s Python 3.2 (binary) : 0.14s . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 72 / 91
  • 126. I/O Performance zapis zapis 100 Mb tekstu do pliku open("foo.txt","wt").write(text) Python 2.7.1 : 1.73s Python 3.2 (UTF-8) : 1.85s . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 73 / 91
  • 127. I/O Performance zapis zapis 100 Mb tekstu do pliku open("foo.txt","wt").write(text) Python 2.7.1 : 1.73s Python 3.2 (UTF-8) : 1.85s zapis 100 Mb danych binarnych data = open("big.bin","wb").write(data) Python 2.7.1 : 1.79s Python 3.2 (binary) : 1.80s . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 73 / 91
  • 128. I/O Performance iteracja zapis 100 Mb tekstu do pliku for line in open("biglog.txt"): pass Python 2.7.1 : 0.25s Python 3.2 (UCS-2, UTF-8) : 0.57s Python 3.2 (UCS-4, UTF-8) : 0.82s . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 74 / 91
  • 129. I/O Performance iteracja zapis 100 Mb tekstu do pliku for line in open("biglog.txt"): pass Python 2.7.1 : 0.25s Python 3.2 (UCS-2, UTF-8) : 0.57s Python 3.2 (UCS-4, UTF-8) : 0.82s zapis 100 Mb danych binarnych for line in open("biglog.txt","rb"): pass Python 2.7.1 : 0.25s Python 3.2 (binary) : 0.29s . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 74 / 91
  • 130. I/O - komentarze odczyt zapis tak czy siak sprowadza się do zapisu bajtów . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 75 / 91
  • 131. I/O - komentarze odczyt zapis tak czy siak sprowadza się do zapisu bajtów aby odczytać tekst, każdy znak musi zostać skopiowany do ”‘intów”’ . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 75 / 91
  • 132. I/O - komentarze odczyt zapis tak czy siak sprowadza się do zapisu bajtów aby odczytać tekst, każdy znak musi zostać skopiowany do ”‘intów”’ aby uniknąć tych kopiowań należy nie korzystać z trybu tekstowego (nie konwertować bytes do unicode). Jednak nie zawsze oznacza to praktycznie rozwiązanie. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 75 / 91
  • 133. I/O - komentarze odczyt zapis tak czy siak sprowadza się do zapisu bajtów aby odczytać tekst, każdy znak musi zostać skopiowany do ”‘intów”’ aby uniknąć tych kopiowań należy nie korzystać z trybu tekstowego (nie konwertować bytes do unicode). Jednak nie zawsze oznacza to praktycznie rozwiązanie. TEKST ZAWSZE POWINIEN BYĆ PRZETWARZANY ZA POMOCĄ UNICODE . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 75 / 91
  • 134. I/O, optymalizacja pracy z unicode Jeśli mamy do czynienia z olbrzymią ilością TEKSTU jednobajtowego (ASCII, Latin-x, ...), a mammy małą ilość dostępnej pamięci można użyć paru optymalizacji Odłożyć konwersje do Unicode jak najpóźniej się da . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 76 / 91
  • 135. I/O, optymalizacja pracy z unicode Jeśli mamy do czynienia z olbrzymią ilością TEKSTU jednobajtowego (ASCII, Latin-x, ...), a mammy małą ilość dostępnej pamięci można użyć paru optymalizacji Odłożyć konwersje do Unicode jak najpóźniej się da parsowanie tekstu jednobajtowego można dokonać na poziomie bytes. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 76 / 91
  • 136. I/O, optymalizacja pracy z unicode Jeśli mamy do czynienia z olbrzymią ilością TEKSTU jednobajtowego (ASCII, Latin-x, ...), a mammy małą ilość dostępnej pamięci można użyć paru optymalizacji Odłożyć konwersje do Unicode jak najpóźniej się da parsowanie tekstu jednobajtowego można dokonać na poziomie bytes. Przykład: parsowanie logów . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 76 / 91
  • 137. I/O, optymalizacja pracy z unicode Przykład Znaleźć wszystkie URL, które spowodowały status 404 w logach Apache. Pomysły? . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 77 / 91
  • 138. I/O, optymalizacja pracy z unicode Przykład Znaleźć wszystkie URL, które spowodowały status 404 w logach Apache. Pomysły? error_404_urls = set() for line in open("biglog.txt","rb"): fields = line.split() if fields[-2] == b'404': error_404_urls.add(fields[-4]) error_404_urls = {n.decode('latin-1') for n in error_404_urls } for name in error_404_urls: print(name) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 77 / 91
  • 139. Table of Contents 1. Wstęp 2. Python 3 3. Tekst 4. Formatowanie tesktu 5. Dane binarne 6. Moduł I/O 7. System Interface 8. Projektowanie bibliotek . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 78 / 91
  • 140. operacje systemowe Do obsługi operacji systemowych Python wykorzystuje zapytania systemowe z biblioteki C . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 79 / 91
  • 141. operacje systemowe Do obsługi operacji systemowych Python wykorzystuje zapytania systemowe z biblioteki C Przykład wywołania zapytania systemowe w POSIX na Unixie: int fd = open(filename, O_RDONLY); . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 79 / 91
  • 142. operacje systemowe Do obsługi operacji systemowych Python wykorzystuje zapytania systemowe z biblioteki C Przykład wywołania zapytania systemowe w POSIX na Unixie: int fd = open(filename, O_RDONLY); atrybuty są przekazywane do zapytań systemowych (nazwy plików, programów, …) jako ciągi znaków (w C - char*, Python - bytes) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 79 / 91
  • 143. operacje systemowe Do obsługi operacji systemowych Python wykorzystuje zapytania systemowe z biblioteki C Przykład wywołania zapytania systemowe w POSIX na Unixie: int fd = open(filename, O_RDONLY); atrybuty są przekazywane do zapytań systemowych (nazwy plików, programów, …) jako ciągi znaków (w C - char*, Python - bytes) Bytes są używane w zmiennych środowiskowych, argumentach wywołania (command line arguments) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 79 / 91
  • 144. operacje systemowe Do obsługi operacji systemowych Python wykorzystuje zapytania systemowe z biblioteki C Przykład wywołania zapytania systemowe w POSIX na Unixie: int fd = open(filename, O_RDONLY); atrybuty są przekazywane do zapytań systemowych (nazwy plików, programów, …) jako ciągi znaków (w C - char*, Python - bytes) Bytes są używane w zmiennych środowiskowych, argumentach wywołania (command line arguments) Jak Python integruje swoje stringi (Unicode) z byte-oriented interfejsem systemowym? . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 79 / 91
  • 145. operacje systemowe kodowanie argumentów Standardowo python3 koduje wszystkie parametry ”‘tekstowe”’ w UTF-8 . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 80 / 91
  • 146. operacje systemowe kodowanie argumentów Standardowo python3 koduje wszystkie parametry ”‘tekstowe”’ w UTF-8 ogólnie jest to bezpieczne założenie. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 80 / 91
  • 147. operacje systemowe kodowanie argumentów Standardowo python3 koduje wszystkie parametry ”‘tekstowe”’ w UTF-8 ogólnie jest to bezpieczne założenie. podobnie z argumentami wywołania i zmiennymi środowiskowymi - Python3 dekoduje je za pomocą UTF-8. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 80 / 91
  • 148. operacje systemowe kodowanie argumentów Standardowo python3 koduje wszystkie parametry ”‘tekstowe”’ w UTF-8 ogólnie jest to bezpieczne założenie. podobnie z argumentami wywołania i zmiennymi środowiskowymi - Python3 dekoduje je za pomocą UTF-8. Jest to dość subtelne zachowanie - gdyż zakłada że wszystkie opcje parametry systemowe są kodowane w UTF-8 . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 80 / 91
  • 149. operacje systemowe kodowanie argumentów Standardowo python3 koduje wszystkie parametry ”‘tekstowe”’ w UTF-8 ogólnie jest to bezpieczne założenie. podobnie z argumentami wywołania i zmiennymi środowiskowymi - Python3 dekoduje je za pomocą UTF-8. Jest to dość subtelne zachowanie - gdyż zakłada że wszystkie opcje parametry systemowe są kodowane w UTF-8 ale niekoniecznie tak musi być . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 80 / 91
  • 150. operacje systemowe - kodowanie nazw Przykład - błąd w nazwie pliku Za pomocą Python2 stworzymy plik w systemie Linux, którego nazwa będzie zawierać jeden znak spoza ASCII: >>> f = open("jalapexf1o.txt","w") >>> f.write("Bwahahahaha!n") >>> f.close() . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 81 / 91
  • 151. operacje systemowe - kodowanie nazw Przykład - błąd w nazwie pliku Za pomocą Python2 stworzymy plik w systemie Linux, którego nazwa będzie zawierać jeden znak spoza ASCII: >>> f = open("jalapexf1o.txt","w") >>> f.write("Bwahahahaha!n") >>> f.close() Python3 nie będzie w stanie otworzyć tego pliku. >>> f = open("jalapexf1o.txt") Traceback (most recent call last): ... IOError: [Errno 2] No such file or directory: 'jalapeño.txt' Powód: nazwa pliku po zakodowaniu w UTF-8 nie odpowiada nazwie pliku w systemie: ”jalapexf1o.txt” → UTF-8 coder → b”jalapec3xb1o.txt” . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 81 / 91
  • 152. operacje systemowe - kodowanie nazw Przykład - błąd w nazwie pliku Za pomocą Python2 stworzymy plik w systemie Linux, którego nazwa będzie zawierać jeden znak spoza ASCII: >>> f = open("jalapexf1o.txt","w") >>> f.write("Bwahahahaha!n") >>> f.close() Python3 nie będzie w stanie otworzyć tego pliku. >>> f = open("jalapexf1o.txt") Traceback (most recent call last): ... IOError: [Errno 2] No such file or directory: 'jalapeño.txt' Powód: nazwa pliku po zakodowaniu w UTF-8 nie odpowiada nazwie pliku w systemie: ”jalapexf1o.txt” → UTF-8 coder → b”jalapec3xb1o.txt” Co się stanie gdy w directory listing będzie nazwa pliku nie UTF-8? . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 81 / 91
  • 153. operacje systemowe - kodowanie nazw argumenty jako Bytes Można użyć bytes zamiast unicode jako argumenty do wywołań systemowych. >>> f = open(b"jalapexf1o.txt") >>> files = glob.glob(b"*.txt") >>> files [b'jalapexf1o.txt', b'spam.txt'] . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 82 / 91
  • 154. operacje systemowe - kodowanie nazw argumenty jako Bytes Można użyć bytes zamiast unicode jako argumenty do wywołań systemowych. >>> f = open(b"jalapexf1o.txt") >>> files = glob.glob(b"*.txt") >>> files [b'jalapexf1o.txt', b'spam.txt'] Jeśli użyjemy bytes do wywołania systemowego, wtedy ciąg ten nie będzie w ogóle kodowany, oraz zwracane wyniki będą podawane jako bytes. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 82 / 91
  • 155. Surrogate Encoding W Pythonie3.1 każdy nie dekodowalny (nie ASCII) znak w nazwie pliku lub parametrze interfejsu systemowego jest tłumaczony przez Surrogate Encoding Jest to specyficzny dla Pythona trik, który zapobiega błędom podczas wywołań systemowych przy obsłudze argumentów które nie są poprawnymi ciągami UTF-8. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 83 / 91
  • 156. Surrogate Encoding definicja Każdy bajt ∈ [0x80; 0xff] zamieniany jest na znak unicode ∈ [U + DC80; U + DCFF] . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 84 / 91
  • 157. Surrogate Encoding definicja Każdy bajt ∈ [0x80; 0xff] zamieniany jest na znak unicode ∈ [U + DC80; U + DCFF] Przykład: ”jalapexf1o.txt” → b”jalapeudcf1o.txt” . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 84 / 91
  • 158. Surrogate Encoding definicja Każdy bajt ∈ [0x80; 0xff] zamieniany jest na znak unicode ∈ [U + DC80; U + DCFF] Przykład: ”jalapexf1o.txt” → b”jalapeudcf1o.txt” Podobnie znaki unicode ∈ [U + DC80; U + DCFF] są zamieniane na bajty ∈ [0x80; 0xff] kiedy występuję w argumentach funkcji interfejsu systemowego . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 84 / 91
  • 159. Surrogate Encoding Przykład Jeśli w wywołaniu systemowy widać znak rodzaju udcxx znaczy to że znak nie ASCII został przesłany do interfejsu systemowego >>> glob.glob("*.txt") [ 'jalapeudcf1o.txt', 'spam.txt'] >>> f = open("jalapeudcf1o.txt") . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 85 / 91
  • 160. Surrogate Encoding integracja z Unicode Czy Surrogate Encoding jest kompatybilne z Unicode? . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 86 / 91
  • 161. Surrogate Encoding integracja z Unicode Czy Surrogate Encoding jest kompatybilne z Unicode? Nie do końca . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 86 / 91
  • 162. Surrogate Encoding integracja z Unicode Czy Surrogate Encoding jest kompatybilne z Unicode? Nie do końca Poprawny unicode nie zawiera znaków ∈ [U + DC80; U + DCFF] . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 86 / 91
  • 163. Surrogate Encoding integracja z Unicode Czy Surrogate Encoding jest kompatybilne z Unicode? Nie do końca Poprawny unicode nie zawiera znaków ∈ [U + DC80; U + DCFF] na przykład używanie napisów z surrogate encoding powoduje wyjątki w funkcji print() >>> files = glob.glob("*.txt") >>> files [ 'jalapeudcf1o.txt', 'spam.txt'] >>> for name in files: print(name) ... Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'utf-8' codec can't␣encode␣character 'udcf1'␣in␣position␣6:␣surrogates␣not␣allowed . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 86 / 91
  • 164. Surrogate Encoding Implementacja Surrogate encoding zaimplementowane jest jako error handler dla metod encode(), decode() - patrz help(encode) >>> s = b"jalapexf1o.txt" >>> t = s.decode('utf-8','surrogateescape') >>> t 'jalapeudcf1o.txt' >>> t.encode('utf-8','surrogateescape') b'jalapexf1o.txt' . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 87 / 91
  • 165. Surrogate Encoding Implementacja Surrogate encoding zaimplementowane jest jako error handler dla metod encode(), decode() - patrz help(encode) >>> s = b"jalapexf1o.txt" >>> t = s.decode('utf-8','surrogateescape') >>> t 'jalapeudcf1o.txt' >>> t.encode('utf-8','surrogateescape') b'jalapexf1o.txt' Jeśli rozważamy pisanie kodu, który ma do czynienia z interfejsem systemowy, i chcemy żeby kod był przenośny, wtedy będziemy potrzebować powyższych rozwiązań. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 87 / 91
  • 166. Table of Contents 1. Wstęp 2. Python 3 3. Tekst 4. Formatowanie tesktu 5. Dane binarne 6. Moduł I/O 7. System Interface 8. Projektowanie bibliotek . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 88 / 91
  • 167. Unicode i Bytes a biblioteki W Pyhon2 mogliśmy pomijać różnice między tekstem a ciągiem bajtów. Wiele bibliotek pomijało tą sprawę (moduły sieciowe, moduły przetwarzania danych …) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 89 / 91
  • 168. Unicode i Bytes a biblioteki W Pyhon2 mogliśmy pomijać różnice między tekstem a ciągiem bajtów. Wiele bibliotek pomijało tą sprawę (moduły sieciowe, moduły przetwarzania danych …) Python3 traktuje tą sprawę poważnie i musimy być precyzyjni w obsłudze I/O . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 89 / 91
  • 169. Unicode i Bytes a biblioteki Przykład Niepoprawna funkcja: def send_response(s,code,msg): s.sendall("HTTP/1.0␣%s␣%srn" % (code,msg)) send_response(s,"200","OK") . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 90 / 91
  • 170. Unicode i Bytes a biblioteki Przykład Niepoprawna funkcja: def send_response(s,code,msg): s.sendall("HTTP/1.0␣%s␣%srn" % (code,msg)) send_response(s,"200","OK") Funkcja jest niepoprawna ponieważ socket operuje tylko na danych binarnych (bytes, bytearray). Czyli nie możemy wysyłać tekstu (np: ”‘Hello!”’) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 90 / 91
  • 171. Unicode i Bytes a biblioteki Przykład W Python3 trzeba podać dokładnie kodowanie tekstu: def send_response(s,code,msg): resp = "HTTP/1.0␣%s␣%srn" % (code,msg) s.sendall(resp.encode('ascii')) send_response(s,"200","OK") . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 91 / 91
  • 172. Unicode i Bytes a biblioteki Przykład W Python3 trzeba podać dokładnie kodowanie tekstu: def send_response(s,code,msg): resp = "HTTP/1.0␣%s␣%srn" % (code,msg) s.sendall(resp.encode('ascii')) send_response(s,"200","OK") Zasady wysyłania danych: . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 91 / 91
  • 173. Unicode i Bytes a biblioteki Przykład W Python3 trzeba podać dokładnie kodowanie tekstu: def send_response(s,code,msg): resp = "HTTP/1.0␣%s␣%srn" % (code,msg) s.sendall(resp.encode('ascii')) send_response(s,"200","OK") Zasady wysyłania danych: Każdy tekst wysyłany musi być najpierw kodowany do bytes . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 91 / 91
  • 174. Unicode i Bytes a biblioteki Przykład W Python3 trzeba podać dokładnie kodowanie tekstu: def send_response(s,code,msg): resp = "HTTP/1.0␣%s␣%srn" % (code,msg) s.sendall(resp.encode('ascii')) send_response(s,"200","OK") Zasady wysyłania danych: Każdy tekst wysyłany musi być najpierw kodowany do bytes Każdy tekst odbierany musi być najpierw dekodowany do unicode (jeśli chcemy nim operować jako tekst) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 91 / 91