Zanurkuj w Pythonie/Formatowanie napisów w oparciu o słowniki: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
zamiana {{Nawigacja|Python|->{{Nawigacja|Zanurkuj w Pythonie| [[Python/->[[../
Piotr (dyskusja | edycje)
poprawki
Linia 1:
{{Podświetl|py}}
== Formatowanie napisów w oparciu o słowniki ==
 
Dlaczego uczyliśmy się na temat funkcji <ttcode>locals</ttcode> i <ttcode>globals</ttcode>? Ponieważ teraz możemy się nauczyć formatowania napisów w oparciu o słowniki. Jak już mówiliśmy, [[../Formatowanie łańcucha znaków|regularne formatowanie napisów]] umożliwia w łatwy sposób wstawianie wartości do napisów. Wartości są wyszczególnione w krotce i w odpowiednim porządku wstawione do napisu, gdzie występuje pole formatujące. O ile jest to skuteczne, nie zawsze tworzy kod łatwy do czytania, zwłaszcza, gdy zostaje wstawianych wiele wartości. Żeby zrozumieć o co chodzi, nie wystarczy po prostu jednorazowo prześledzić napis; trzeba ciągle skakać między czytanym napisem, a czytaną krotką wartości.
 
Tutaj mamy alternatywną formę formatowania napisu, a która zamiast krotek wykorzystuje słowniki.
 
'''{{Python/Przykład
|8.13. |Formatowanie napisów w oparciu o słowniki'''
|tekst=
 
>>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"}
>>> "%(pwd)s" % params #(1)
{{samp|'secret'}}
>>> "%(pwd)s isnie notjest apoprawnym goodhasłem password fordla %(uid)s" % params #(2)
{{samp|'secret isnie notjest apoprawnym goodhasłem password fordla sa'}}
>>> "%(database)s of mind, %(database)s of body" % params #(3)
{{samp|'master of mind, master of body'}}
 
# Zamiast korzystać z krotki wartości, formujemy napis formatujący, który korzysta ze słownika <ttcode>params</ttcode>. Ponadto zamiast prostego pola <ttcode>%s</ttcode> w napisie, pole zawiera nazwę w nawiasach okrągłych. Nazwa ta jest wykorzystana jako klucz w słowniku <ttcode>params</ttcode> i zostaje zastąpionazastąpione odpowiednią wartością, <ttcode>secret</ttcode>, w miejscu wystąpienia pola <ttcode>%(pwd)s</ttcode>.
# Takie formatowanie może posiadać dowolną liczbę odwołań do kluczy. Każdy klucz musi istnieć w podanym słowniku, ponieważ inaczej formatowanie zakończy się niepowodzeniem i zostanie wyrzuconyrzucony wyjątek <ttcode>KeyError</ttcode>.
# MożeszMożemy nawet wykorzystać ten sam klucz dwakilka razy. Każde wystąpienie zostanie zastąpione odpowiednią wartością.
}}
 
Zatem dlaczego używać formatowania napisu w oparciu o słowniki? Może to wyglądać na nadmierne wmieszanie słownika z kluczami i wartościami, aby wykonać proste formatowanie napisu. W rzeczywistości jest bardzo przydatne, kiedy już się ma słownik z kluczami o sensownych nazwach i wartościach, jak np. <ttcode>locals</ttcode>.
 
{{Python/Przykład
'''Przykład |8.14. |Formatowanie napisu w <tt>{{Python/Src|BaseHTMLProcessor.py</tt>'''}}
|tekst=
<nowiki>
def handle_comment(self, text):
Linia 28 ⟶ 31:
</nowiki>
 
# Formatowanie za pomocą słowników jest bardzo powszechnie używane z wbudowaną funkcję <ttcode>locals</ttcode>. Oznacza to, że możeszmożemy wykorzystywać nazwy zmiennych lokalnych wewnątrz swojego napisu formatującego (w tym przypadku, <ttcode>text</ttcode>, który został przykazany jako argument do metody klasy) i każda nazwa zmiennej zostanie zastąpiona jej wartością. Jeśli <ttcode>text</ttcode> przechowuje wartość <ttcode>'BeginPoczątek page footerstopki'</ttcode>, formatowany napis <ttcode><nowiki>"<!--%(text)s-->" % locals()</nowiki></ttcode> zostanie wygenerowany jako <ttcode><nowiki>'<!--Begin pagePoczątek footerstopki-->'</nowiki></tt>.
}}
 
'''Przykład 8.15. Więcej formatowania opartego na słownikach'''
 
{{Python/Przykład
'''Przykład |8.15. |Więcej formatowania opartego na słownikach'''
|tekst=
def unknown_starttag(self, tag, attrs):
strattrs = "".join([' %s="%s"' % (key, value) for key, value in attrs]) #(1)
self.pieces.append("<%(tag)s%(strattrs)s>" % locals()) #(2)
 
# Kiedy metoda ta zostaje wywołana, <ttcode>attrs</ttcode> jest listą krotek postaci klucz/wartość, podobnie jak zwrócona wartość [[../Odwzorowywanie listy#przy-3.28|metody słownika <ttcode>items</ttcode>]], a coto oznacza, że możemy wykorzystać [[../Deklarowanie zmiennych#Wielozmienne przypisania|wielozmienne przypisanie]], aby wykonać przeiterowaćna niej iterację. PowinieneśPowinniśmy już być zaznajomionyzaznajomieni z wzorcamitymi operacjami, ale tutajjest tu wykonujemytego wieletrochę operacjidużo, więc prześledźmy je po kolei:
## Przypuśćmy, że <ttcode>attrs</ttcode> wynosi [('href', 'index.html'), ('title', 'GoIdź todo homestrony pagedomowej')].
## W pierwszym przebiegu odwzorowywania listy, <ttcode>key</ttcode> weźmieprzyjmie wartość <ttcode>'href'</ttcode>, a <ttcode>value</ttcode> weźmie wartość <ttcode>'index.html'</ttcode>.
## Formatowanie napisu <ttcode>' %s="%s"' % (key, value)</ttcode> przekształci się na <ttcode>' href="index.html"'</ttcode>. Napis ten będzie pierwszym elementem zwróconej listy.
## W drugim przebiegu, <ttcode>key</ttcode> przyjmie wartość <ttcode>'title'</ttcode>, a <ttcode>value</ttcode> wartość <ttcode>'GoIdź todo homestrony pagedomowej'</ttcode>.
## Formatowanie napisu przekształci to na <ttcode>' title="GoIdź todo homestrony pagedomowej"'</ttcode>.
## Po wykonaniu wyrażenia listowego, zwrócona lista będzie przechowywała te dwa wygenerowane napisy, a <ttcode>strattrs</ttcode> będzie połączeniem obydwu tych elementów, czyli będzie przechowywał <ttcode>' href="index.html" title="Go to home page"'</ttcode>.
# Teraz formatując napis za pomocą słownika, wstawiamy wartość zmiennej <ttcode>tag</ttcode> i <ttcode>strattrs</ttcode> do napisu. Zatem jeśli <ttcode>tag</ttcode> wynosił <ttcode>'a'</ttcode>, w ostateczności otrzymamy wynik <ttcode><nowiki>'<a href="index.html" title="GoIdź todo homestrony pagedomowej'">'</nowiki></tt> i to następnie dodajemy do <ttcode>self.pieces</ttcode>.
}}
 
{{Uwaga|
Korzystanie z słownikowego formatowania napisu za pomocą słownika i funkcji <ttcode>locals</ttcode> jest wygodnym sposobem, aby tworzyć czytelniejsze skomplikowane wyrażenia listowe, lecz trzeba zapłacić pewną cenę. Jest tutaj drobny narzut wydajności, a jest to związanezwiązany z wywołaniem funkcji <ttcode>locals</ttcode>, ponieważ <ttcode>locals</ttcode> wykonuje kopię lokalnej przestrzeni nazw.
}}
 
<noinclude>
{{Nawigacja|Zanurkuj w Pythonie|
[[../locals i globals|<ttcode>locals</ttcode> i <ttcode>globals</ttcode>]]|
[[../Dodawanie cudzysłowów do wartości atrybutów|Dodawanie cudzysłowów do wartości atrybutów/]]|
}}
{{Podświetl|py}}
</noinclude>