SlideShare uma empresa Scribd logo
1 de 174
Baixar para ler offline
.
.
.
.
.
.
.
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
BufferedReader
FileIO
.buffer
.raw
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

Mais conteúdo relacionado

Destaque

Making changes
Making changesMaking changes
Making changespri_ox
 
The Normative Dimensions of SBC as Part of a Community Action Cycle SUSAN IGRAS
The Normative Dimensions of SBC as Part of a Community Action Cycle SUSAN IGRASThe Normative Dimensions of SBC as Part of a Community Action Cycle SUSAN IGRAS
The Normative Dimensions of SBC as Part of a Community Action Cycle SUSAN IGRASCORE Group
 
Slom komunizma u Europi
Slom komunizma u EuropiSlom komunizma u Europi
Slom komunizma u EuropiVale Shau
 
reglamento estudiantil universidad de pamplona
reglamento estudiantil universidad de pamplonareglamento estudiantil universidad de pamplona
reglamento estudiantil universidad de pamplonaKatherine Rodriguez
 
European Delivery at the Kundencenter - Mercedes-Benz E350 BlueTec
European Delivery at the Kundencenter - Mercedes-Benz E350 BlueTecEuropean Delivery at the Kundencenter - Mercedes-Benz E350 BlueTec
European Delivery at the Kundencenter - Mercedes-Benz E350 BlueTecThe Diesel Driver
 
Powerpoint de cs.sociales población bárbara giordano
Powerpoint de cs.sociales población bárbara giordanoPowerpoint de cs.sociales población bárbara giordano
Powerpoint de cs.sociales población bárbara giordanobiblioteca 7 de 10
 
]project-open[ on Amazon AWS
]project-open[ on Amazon AWS]project-open[ on Amazon AWS
]project-open[ on Amazon AWSKlaus Hofeditz
 
Python3 cheatsheet
Python3 cheatsheetPython3 cheatsheet
Python3 cheatsheetGil Cohen
 
Voda na Zemlji
Voda na ZemljiVoda na Zemlji
Voda na Zemljibatica1
 
Loris Zagvozda, 5. razred - Voda na Zemlji
Loris Zagvozda, 5. razred - Voda na ZemljiLoris Zagvozda, 5. razred - Voda na Zemlji
Loris Zagvozda, 5. razred - Voda na ZemljiMoja Geografija
 
SOSIOEKONOMI PADA ZAMAN KOLONIAL
SOSIOEKONOMI PADA ZAMAN KOLONIALSOSIOEKONOMI PADA ZAMAN KOLONIAL
SOSIOEKONOMI PADA ZAMAN KOLONIALsyuherna nandu
 

Destaque (16)

Making changes
Making changesMaking changes
Making changes
 
Dame Shirley Porter - Porter School "Building for change"
Dame Shirley Porter - Porter School "Building for change"Dame Shirley Porter - Porter School "Building for change"
Dame Shirley Porter - Porter School "Building for change"
 
The Normative Dimensions of SBC as Part of a Community Action Cycle SUSAN IGRAS
The Normative Dimensions of SBC as Part of a Community Action Cycle SUSAN IGRASThe Normative Dimensions of SBC as Part of a Community Action Cycle SUSAN IGRAS
The Normative Dimensions of SBC as Part of a Community Action Cycle SUSAN IGRAS
 
Slom komunizma u Europi
Slom komunizma u EuropiSlom komunizma u Europi
Slom komunizma u Europi
 
Diaposeq5
Diaposeq5Diaposeq5
Diaposeq5
 
Participatory fiction
Participatory fictionParticipatory fiction
Participatory fiction
 
reglamento estudiantil universidad de pamplona
reglamento estudiantil universidad de pamplonareglamento estudiantil universidad de pamplona
reglamento estudiantil universidad de pamplona
 
European Delivery at the Kundencenter - Mercedes-Benz E350 BlueTec
European Delivery at the Kundencenter - Mercedes-Benz E350 BlueTecEuropean Delivery at the Kundencenter - Mercedes-Benz E350 BlueTec
European Delivery at the Kundencenter - Mercedes-Benz E350 BlueTec
 
Diashow1
Diashow1Diashow1
Diashow1
 
Powerpoint de cs.sociales población bárbara giordano
Powerpoint de cs.sociales población bárbara giordanoPowerpoint de cs.sociales población bárbara giordano
Powerpoint de cs.sociales población bárbara giordano
 
]project-open[ on Amazon AWS
]project-open[ on Amazon AWS]project-open[ on Amazon AWS
]project-open[ on Amazon AWS
 
Python3 cheatsheet
Python3 cheatsheetPython3 cheatsheet
Python3 cheatsheet
 
Voda na Zemlji
Voda na ZemljiVoda na Zemlji
Voda na Zemlji
 
Kemajuan peradaban
Kemajuan peradabanKemajuan peradaban
Kemajuan peradaban
 
Loris Zagvozda, 5. razred - Voda na Zemlji
Loris Zagvozda, 5. razred - Voda na ZemljiLoris Zagvozda, 5. razred - Voda na Zemlji
Loris Zagvozda, 5. razred - Voda na Zemlji
 
SOSIOEKONOMI PADA ZAMAN KOLONIAL
SOSIOEKONOMI PADA ZAMAN KOLONIALSOSIOEKONOMI PADA ZAMAN KOLONIAL
SOSIOEKONOMI PADA ZAMAN KOLONIAL
 

Semelhante a Python io

Erlang
ErlangErlang
Erlangkonryd
 
Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010Natalia Stanko
 
Przekierowanie strumienia danych
Przekierowanie strumienia danychPrzekierowanie strumienia danych
Przekierowanie strumienia danychJacek Tomczak
 
Let's Go! - wprowadzenie do Go
Let's Go!  - wprowadzenie do GoLet's Go!  - wprowadzenie do Go
Let's Go! - wprowadzenie do GoRafal Piekarski
 
ARM CoreSight - sprawdź, co tak naprawdę robi Twój SoC.
ARM CoreSight - sprawdź, co tak naprawdę robi Twój SoC.ARM CoreSight - sprawdź, co tak naprawdę robi Twój SoC.
ARM CoreSight - sprawdź, co tak naprawdę robi Twój SoC.Semihalf
 
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
 
Programowanie Komponentowe: #5 Wprowadzenie do środowiska .NET
Programowanie Komponentowe: #5 Wprowadzenie do środowiska .NETProgramowanie Komponentowe: #5 Wprowadzenie do środowiska .NET
Programowanie Komponentowe: #5 Wprowadzenie do środowiska .NETMikołaj Olszewski
 
Hierarchia pamięci w systemach komputerowych.
Hierarchia pamięci w systemach komputerowych.Hierarchia pamięci w systemach komputerowych.
Hierarchia pamięci w systemach komputerowych.Wojciech Szymański
 
Hierarchia pamięci w systemach komputerowych.
Hierarchia pamięci w systemach komputerowych.Hierarchia pamięci w systemach komputerowych.
Hierarchia pamięci w systemach komputerowych.Semihalf
 
Agregacja i analiza logów
Agregacja i analiza logówAgregacja i analiza logów
Agregacja i analiza logówDivante
 
Tomasz Kopacz MTS 2012 Wind RT w Windows 8 i tzw aplikacje lob (line of busin...
Tomasz Kopacz MTS 2012 Wind RT w Windows 8 i tzw aplikacje lob (line of busin...Tomasz Kopacz MTS 2012 Wind RT w Windows 8 i tzw aplikacje lob (line of busin...
Tomasz Kopacz MTS 2012 Wind RT w Windows 8 i tzw aplikacje lob (line of busin...Tomasz Kopacz
 
Seminarium .Net CF 2004
Seminarium .Net CF 2004Seminarium .Net CF 2004
Seminarium .Net CF 2004Tomasz Cieplak
 

Semelhante a Python io (20)

Python IO
Python IOPython IO
Python IO
 
Erlang
ErlangErlang
Erlang
 
Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010
 
Jak działa CPython
Jak działa CPythonJak działa CPython
Jak działa CPython
 
Python. Od podstaw
Python. Od podstawPython. Od podstaw
Python. Od podstaw
 
Przekierowanie strumienia danych
Przekierowanie strumienia danychPrzekierowanie strumienia danych
Przekierowanie strumienia danych
 
Let's Go! - wprowadzenie do Go
Let's Go!  - wprowadzenie do GoLet's Go!  - wprowadzenie do Go
Let's Go! - wprowadzenie do Go
 
ARM CoreSight - sprawdź, co tak naprawdę robi Twój SoC.
ARM CoreSight - sprawdź, co tak naprawdę robi Twój SoC.ARM CoreSight - sprawdź, co tak naprawdę robi Twój SoC.
ARM CoreSight - sprawdź, co tak naprawdę robi Twój SoC.
 
OpenEmbedded
OpenEmbeddedOpenEmbedded
OpenEmbedded
 
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...
 
Programowanie Komponentowe: #5 Wprowadzenie do środowiska .NET
Programowanie Komponentowe: #5 Wprowadzenie do środowiska .NETProgramowanie Komponentowe: #5 Wprowadzenie do środowiska .NET
Programowanie Komponentowe: #5 Wprowadzenie do środowiska .NET
 
DSL - DYI
DSL - DYIDSL - DYI
DSL - DYI
 
Iron Python I Dlr
Iron Python I DlrIron Python I Dlr
Iron Python I Dlr
 
Ubuntu server
Ubuntu serverUbuntu server
Ubuntu server
 
Hierarchia pamięci w systemach komputerowych.
Hierarchia pamięci w systemach komputerowych.Hierarchia pamięci w systemach komputerowych.
Hierarchia pamięci w systemach komputerowych.
 
Hierarchia pamięci w systemach komputerowych.
Hierarchia pamięci w systemach komputerowych.Hierarchia pamięci w systemach komputerowych.
Hierarchia pamięci w systemach komputerowych.
 
Przetwarzanie i ocr czasopism drukowanych gotykiem - krok po kroku
Przetwarzanie i ocr czasopism drukowanych gotykiem - krok po kroku Przetwarzanie i ocr czasopism drukowanych gotykiem - krok po kroku
Przetwarzanie i ocr czasopism drukowanych gotykiem - krok po kroku
 
Agregacja i analiza logów
Agregacja i analiza logówAgregacja i analiza logów
Agregacja i analiza logów
 
Tomasz Kopacz MTS 2012 Wind RT w Windows 8 i tzw aplikacje lob (line of busin...
Tomasz Kopacz MTS 2012 Wind RT w Windows 8 i tzw aplikacje lob (line of busin...Tomasz Kopacz MTS 2012 Wind RT w Windows 8 i tzw aplikacje lob (line of busin...
Tomasz Kopacz MTS 2012 Wind RT w Windows 8 i tzw aplikacje lob (line of busin...
 
Seminarium .Net CF 2004
Seminarium .Net CF 2004Seminarium .Net CF 2004
Seminarium .Net CF 2004
 

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 BufferedReader FileIO .buffer .raw 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