Zanurkuj w Pythonie/plural.py, etap 3
Zauważmy, że definiowanie osobnych, nazwanych funkcji dla każdej reguły dopasowującej i modyfikującej nie jest tak naprawdę konieczne. Nigdy nie wywołujemy tych funkcji bezpośrednio; definiujemy je w krotce rules i wywołujemy je również przy użyciu tej krotki. Spróbujmy zatem przekształcić je do funkcji anonimowych.
Przykład 17.8. plural3.py
import re
rules = \
(
(
lambda word: re.search('[sxz]$', word),
lambda word: re.sub('$', 'es', word)
),
(
lambda word: re.search('[^aeioudgkprt]h$', word),
lambda word: re.sub('$', 'es', word)
),
(
lambda word: re.search('[^aeiou]y$', word),
lambda word: re.sub('y$', 'ies', word)
),
(
lambda word: re.search('$', word),
lambda word: re.sub('$', 's', word)
)
) #(1)
def plural(noun):
for matchesRule, applyRule in rules: #(2)
if matchesRule(noun):
return applyRule(noun)
- To ten sam zestaw reguł, który widzieliśmy na etapie 2. Jedyna różnica polega na tym, że zamiast definiować funkcje nazwane, takie jak match_sxz czy apply_sxz, włączyliśmy treść tych funkcji bezpośrednio do zmiennej rules używając funkcji lambda.
- Zauważmy, że funkcja plural w ogóle sie nie zmieniła. Iteruje ona po zestawie funkcji reprezentujących reguły, sprawdza pierwszą regułę, a jeśli zwróci ona wartość true, wywołuje ona drugą regułę i zwraca jej wynik. Dokładnie tak samo, jak wcześniej. Jedyna różnica polega teraz na tym, że funkcje z regułami zostały zdefiniowane "inline", jako funkcje anonimowe, przy użyciu funkcji lambda. Jednak dla funkcji plural sposób zdefiniowania funkcji nie ma żadnego znaczenia; otrzymuje ona listę reguł i wykonuje na niej swoją pracę.
Aby dodać nową regułę tworzenia liczby mnogiej, wystarczy zdefiniować nowe funkcje (regułę dopasowującą oraz regułę modyfikującą) bezpośrednio w samej krotce rules. Teraz jednak, kiedy mamy zdefiniować reguły wewnątrz krotki, widzimy wyraźnie, że pojawiły się liczne niepotrzebne powtórzenia kodu. Mamy bowiem cztery pary funkcji, a każda z nich jest napisana według tego samego wzorca. Funkcje dopasowujące składają się z pojedynczego wywołania re.search, a funkcje modyfikujące - z wywołania re.sub. Spróbujmy zrefaktoryzować te podobieństwa.