Python IO
Upcoming SlideShare
Loading in...5
×
 

Python IO

on

  • 451 views

Master information about working with python io.

Master information about working with python io.

Statistics

Views

Total Views
451
Views on SlideShare
450
Embed Views
1

Actions

Likes
0
Downloads
2
Comments
0

1 Embed 1

https://duckduckgo.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Python IO Python IO Presentation Transcript

  • . Python Zaawansowane IO przetwarzanie tekstu, input, output. Robert Zaremba Scale it Wrocław 2011 listopad 10 . . . . . .
  • Table of Contents1. Wstęp2. Python 33. Tekst4. Formatowanie tesktu5. Dane binarne6. Moduł I/O7. System Interface8. 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 zapomocą 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 zapomocą narzędzia 2to3Ale 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 Contents1. Wstęp2. Python 33. Tekst4. Formatowanie tesktu5. Dane binarne6. Moduł I/O7. System Interface8. Projektowanie bibliotek . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 6 / 91
  • Python 3składnia print . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 7 / 91
  • Python 3skł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 3built-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 3Porzą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 32to3Przykł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 32to3uż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 32to3uż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 32to3 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: Cant␣convert␣bytes␣object␣to␣str␣implicitlyJak 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 32to3 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: Cant␣convert␣bytes␣object␣to␣str␣implicitlyJak widzimy błąd jest w obsłudze napisów.2to3 nie może zgadnąć o jakie napisy nam chodziFix: LinkPrinter().feed(data.decode(′ utf − 8′ )) . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 12 / 91
  • Python 3I/OPo 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 Contents1. Wstęp2. Python 33. Tekst4. Formatowanie tesktu5. Dane binarne6. Moduł I/O7. System Interface8. Projektowanie bibliotek . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 14 / 91
  • TekstProblemy 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
  • TekstProblemy 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
  • Tekstco 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
  • TekstUnicode 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
  • TekstUnicode 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
  • TekstUnicode 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
  • TekstUnicode 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
  • Teksttesty z konsolątestowanie znaków w python2 i python3methody 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
  • TekstUnicode 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
  • TekstUnicode 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
  • TekstUnicode - 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
  • TekstUnicode - 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
  • TekstUnicode - 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 bJalapexc3xb1o >>> data.decode(utf-8) Jalapeño . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 22 / 91
  • TekstUnicode - 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
  • TekstUnicode - 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 cant␣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
  • TekstUwagi 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 Contents1. Wstęp2. Python 33. Tekst4. Formatowanie tesktu5. Dane binarne6. Moduł I/O7. System Interface8. Projektowanie bibliotek . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 26 / 91
  • Printnowe 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
  • Printnowe 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 tekstufunkcje 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 tekstufunkcje 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 tekstucode 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 tekstucode 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 tekstucode 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 tekstucode 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 tekstucode formatersmetodę __format__(self, fmt) można nadpisać.Wtedy sami możemy interpretować “code formaters” oraz dodawać swojekody. . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 33 / 91
  • Formatowanie tekstustring formatMetoda 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 tekstustring formatJak tworzona jest wartość obiektu który “wkładamy” do koszykaformatera? {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 tekstustring formatJak tworzona jest wartość obiektu który “wkładamy” do koszykaformatera? {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 tekstustring formatJak stworzyć znak ’{’ w formaterze? Trzeba użyć ’{{’ . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 36 / 91
  • Formatowanie tekstuformat_mapMetoda format może korzystać z nazwanych argumentów podczasformatowania tekstu. Jeśli już mamy słownik i nie chcemy nadmiernietworzyć 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 tekstustring.TemplatesPodobną funkcjonalność do formatowania napisów daje klasastring.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 Contents1. Wstęp2. Python 33. Tekst4. Formatowanie tesktu5. Dane binarne6. Moduł I/O7. System Interface8. Projektowanie bibliotek . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 39 / 91
  • BytesdefiniowanieDefiniowanie “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
  • BytesdefiniowanieDefiniowanie “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 stringTworzenie z stringu zawierającego liczbę hexadecimal e = bytes.fromhex("48656c6c6f") . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 40 / 91
  • ByteswłaściwościBytes posiada standardowe metody napisów >>> s = b"ACME␣50␣91.10" >>> s.split() [bACME, b50, b91.10] >>> s.lower() bacme␣50␣91.10 >>> s[5:7] b50 . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 41 / 91
  • ByteswłaściwościBytes posiada standardowe metody napisów >>> s = b"ACME␣50␣91.10" >>> s.split() [bACME, b50, b91.10] >>> s.lower() bacme␣50␣91.10 >>> s[5:7] b50Bytes tak samo jak napisy są niemutowalne . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 41 / 91
  • Byteswł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
  • Byteswł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
  • BytesProblemy 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
  • BytesPortowanie Nie potrzeba używać metody ord . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 44 / 91
  • BytesPortowanie Nie potrzeba używać metody ord konwersja obiektów do “bytes” - postać binarna obiektów: >>> x = 7 >>> bytes(x) bx00x00x00x00x00x00x00 >>> str(x).encode(ascii) b7 . . . . . . 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(bpYTHON␣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(bpYTHON␣50␣91.10") zawiera wiele operacji “listowych” >>> s.append(23) >>> s.append(45) >>> s.extend([1,2,3,4]) >>> s bytearray(bACME␣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 doesnt␣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 doesnt␣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 doesnt␣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 doesnt␣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 bytesprzekazywanie wiadomościPrzekazywanie 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 bytesXOR - cipherkodowanie XOR >>> s = b"Hello␣World" >>> t = bytes(x^42 for x in s) >>> t bbOFFEn}EXFN >>> bytes(x^42 for x in t) bHello␣World . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 50 / 91
  • Użycie bytessuma kontrolnadołą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
  • Buforypodobień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
  • Buforypodobień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
  • Buforypodobień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(bHello␣World) >>> b = memoryview(a) >>> b <memory at 0x1007014d0> >>> b[-5:] = bThere >>> a bytearray(bHello␣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(bHello␣World) >>> b = memoryview(a) >>> b <memory at 0x1007014d0> >>> b[-5:] = bThere >>> a bytearray(bHello␣There) jest bardzo niskopoziomową strukturą . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 53 / 91
  • Table of Contents1. Wstęp2. Python 33. Tekst4. Formatowanie tesktu5. Dane binarne6. Moduł I/O7. System Interface8. 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/Owarstwy 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/OFileIO 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/OFileIO 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/OFileIO 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
  • FileIOuż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
  • Buforyoperacje 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
  • Buforyoperacje 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
  • Buforyoperacje 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
  • UWAGAdla 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
  • Textobsł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
  • Textobsł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
  • Textobsł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
  • Textobsł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
  • Textobsł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
  • Textobsł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 Stackprzechodzenie 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 Stackprzechodzenie 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 Stackprzechodzenie po stosie I/O - przykładPisanie danych binarnych do sys.stdout.Pomysły? . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 70 / 91
  • I/O Stackprzechodzenie po stosie I/O - przykładPisanie 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 StackUWAGA - warstwy!Przechodzenie po warstwach może powodować błędy gdy pracujemy zobjektami 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 Performanceodczyt 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 Performanceodczyt 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 Performancezapis 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 Performancezapis 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 Performanceiteracja 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 Performanceiteracja 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 unicodeJeś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 unicodeJeś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 unicodeJeś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 unicodePrzykładZnaleźć 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 unicodePrzykładZnaleźć 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] == b404: 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 Contents1. Wstęp2. Python 33. Tekst4. Formatowanie tesktu5. Dane binarne6. Moduł I/O7. System Interface8. 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 systemowekodowanie 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 systemowekodowanie 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 systemowekodowanie 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 systemowekodowanie 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 systemowekodowanie 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 nazwPrzykł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 nazwPrzykł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 nazwPrzykł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 nazwargumenty 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 [bjalapexf1o.txt, bspam.txt] . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 82 / 91
  • operacje systemowe - kodowanie nazwargumenty 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 [bjalapexf1o.txt, bspam.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 Encodingdefinicja 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 Encodingdefinicja 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 Encodingdefinicja 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 EncodingPrzykładJeśli w wywołaniu systemowy widać znak rodzaju udcxx znaczy to żeznak 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 Encodingintegracja z Unicode Czy Surrogate Encoding jest kompatybilne z Unicode? . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 86 / 91
  • Surrogate Encodingintegracja 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 Encodingintegracja 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 Encodingintegracja 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 cant␣encode␣character udcf1␣in␣position␣6:␣surrogates␣not␣allowed . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 86 / 91
  • Surrogate EncodingImplementacja 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) bjalapexf1o.txt . . . . . . Robert Zaremba (Scale it) Python Zaawansowane IO Wrocław 2011 listopad 10 87 / 91
  • Surrogate EncodingImplementacja 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) bjalapexf1o.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 Contents1. Wstęp2. Python 33. Tekst4. Formatowanie tesktu5. Dane binarne6. Moduł I/O7. System Interface8. 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 bibliotekiPrzykł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 bibliotekiPrzykł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 bibliotekiPrzykł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 bibliotekiPrzykł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 bibliotekiPrzykł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 bibliotekiPrzykł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