Jaką funkcjonalność functools.partial
oferuje nie można uzyskać przez lambdas?
Niewiele pod względem dodatkowej funkcjonalności (ale zobacz później) - a czytelność zależy od obserwatora.
Większość osób, które są obeznane z funkcjonalnymi językami programowania (szczególnie te z rodzin Lisp / Scheme) wydają się lubić lambda
- mówię „większość”, zdecydowanie nie wszystkie, ponieważ Guido i ja z pewnością należą do osób „zaznajomionych” (itp.) ), ale myślę o lambda
anomalii odleżyn w Pythonie ...
Był skruszony, że kiedykolwiek zaakceptował go w Pythonie, podczas gdy planował usunąć go z Pythona 3, jako jedną z „usterek Pythona”.
W pełni go w tym wspierałem. (Uwielbiam lambda
w Schemacie ... podczas gdy jego ograniczenia w Pythonie i dziwny sposób, że po prostu nie robi resztą języka spraw, by moja skóra czołgała się).
Nie dotyczy to jednak hord lambda
kochanków - którzy zainscenizowali jedną z najbliższych rzeczy buntu, jaką kiedykolwiek widzieliśmy w historii Pythona, dopóki Guido nie wycofał się i nie zdecydował się odejść lambda
.
Kilka możliwych dodatków do functools
(aby funkcje zwracały stałe, tożsamość, itp.) nie nastąpiło (aby uniknąć jawnego powielania większej liczby lambda
funkcji), chociaż partial
oczywiście pozostało (nie jest to całkowite powielanie, ani nie jest odrażeniem).
Pamiętaj, że lambda
ciało jest ograniczone do wyrażania się , więc ma ograniczenia. Na przykład...:
>>> import functools
>>> f = functools.partial(int, base=2)
>>> f.args
()
>>> f.func
<type 'int'>
>>> f.keywords
{'base': 2}
>>>
functools.partial
Zwrócona funkcja jest ozdobiona atrybutami użytecznymi do introspekcji - funkcja ta jest zawijana oraz jakie argumenty pozycyjne i nazwane w niej naprawia. Co więcej, wymienione argumenty można od razu zastąpić („ustalanie” jest raczej w pewnym sensie ustawieniem domyślnym):
>>> f('23', base=10)
23
Tak więc, jak widać, jest to definely nie jest tak proste jak lambda s: int(s, base=2)
! -)
Tak, to mogłoby wykrzywiać swoją lambda dać trochę tego - na przykład dla słowa kluczowego-nadrzędnych,
>>> f = lambda s, **k: int(s, **dict({'base': 2}, **k))
ale mam wielką nadzieję, że nawet najbardziej zagorzały lambda
kochanek nie uważa tego horroru za bardziej czytelny niż partial
wezwanie! -). Część „ustawianie atrybutów” jest jeszcze trudniejsza, ponieważ ograniczenie Pythona do „ciała jest pojedynczym wyrażeniem” lambda
(plus fakt, że przypisanie nigdy nie może być częścią wyrażenia w Pythonie)… w rezultacie „fałszujesz przypisania w wyrażeniu” poprzez rozciągnięcie zrozumienia listy znacznie przekraczając jej granice projektowe ...:
>>> f = [f for f in (lambda f: int(s, base=2),)
if setattr(f, 'keywords', {'base': 2}) is None][0]
Teraz połączyć przeciążania nazwanych argumentów plus ustawienie trzech atrybutów w jednej wypowiedzi, i powiedz mi, w jaki sposób czytelny , że będzie ...!
functools.partial
której wspomniałeś, sprawia, że jest lepsza niż lambda. Być może jest to temat innego postu, ale o co tak bardzo cię martwisz na poziomie projektowanialambda
?