Zanurkuj w Pythonie/Formatowanie napisów w oparciu o słowniki

Formatowanie napisów w oparciu o słowniki

edytuj

Dlaczego uczyliśmy się na temat funkcji locals i globals? Ponieważ teraz możemy się nauczyć formatowania napisów w oparciu o słowniki. Jak już mówiliśmy, 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.

Mamy tutaj alternatywną metodę formatowania napisu, wykorzystującą słowniki zamiast krotek.

Przykład. Formatowanie napisów w oparciu o słowniki
>>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"}
>>> "%(pwd)s" % params                                    #(1)
'secret'
>>> "%(pwd)s nie jest poprawnym hasłem dla %(uid)s" % params #(2)
'secret nie jest poprawnym hasłem dla sa'
>>> "%(database)s of mind, %(database)s of body" % params #(3)
'master of mind, master of body'
  1. Zamiast korzystać z krotki wartości, formujemy napis formatujący, który korzysta ze słownika params. Ponadto zamiast prostego pola %s w napisie, pole zawiera nazwę w nawiasach okrągłych. Nazwa ta jest wykorzystana jako klucz w słowniku params i zostaje zastąpione odpowiednią wartością, secret, w miejscu wystąpienia pola %(pwd)s.
  2. 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 rzucony wyjątek KeyError.
  3. Możemy nawet wykorzystać ten sam klucz kilka 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. locals.

Przykład. Formatowanie napisu w BaseHTMLProcessor.py
     def handle_comment(self, text):        
         self.pieces.append("<!--%(text)s-->" % locals()) #(1)
  1. Formatowanie za pomocą słowników jest powszechnie używane z wbudowaną funkcją locals. Oznacza to, że możemy wykorzystywać nazwy zmiennych lokalnych wewnątrz napisu formatującego (w tym przypadku text, który został przykazany jako argument do metody klasy) i każda nazwa zmiennej zostanie zastąpiona jej wartością. Jeśli text przechowuje wartość 'Początek stopki', formatowany napis "<!--%(text)s-->" % locals() zostanie wygenerowany jako '<!--Początek stopki-->'.
Przykład. Więcej formatowania opartego na słownikach
     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)
  1. Kiedy metoda ta zostaje wywołana, attrs jest listą krotek postaci klucz/wartość, podobnie jak zwrócona wartość metody słownika items, a to oznacza, że możemy wykorzystać wielozmienne przypisanie, aby wykonać na niej iterację. Powinniśmy już być zaznajomieni z tymi operacjami, ale występuje ich tutaj sporo, więc prześledźmy je po kolei:
    1. Przypuśćmy, że attrs wynosi [('href', 'index.html'), ('title', 'Idź do strony domowej')].
    2. W pierwszym przebiegu odwzorowywania listy, key przyjmie wartość 'href', a value weźmie wartość 'index.html'.
    3. Formatowanie napisu ' %s="%s"' % (key, value) przekształci się na ' href="index.html"'. Napis ten będzie pierwszym elementem zwróconej listy.
    4. W drugim przebiegu, key przyjmie wartość 'title', a value wartość 'Idź do strony domowej'.
    5. Formatowanie napisu przekształci to na ' title="Idź do strony domowej"'.
    6. Po wykonaniu wyrażenia listowego zwrócona lista będzie przechowywała te dwa wygenerowane napisy, a strattrs będzie połączeniem obydwu tych elementów, czyli będzie przechowywał ' href="index.html" title="Idź do strony domowej"'.
  2. Teraz formatując napis za pomocą słownika, wstawiamy wartość zmiennej tag i strattrs do napisu. Zatem jeśli tag wynosił 'a', w ostateczności otrzymamy wynik '<a href="index.html" title="Idź do strony domowej'">' i to następnie dodajemy do self.pieces.