Que funcionalidade functools.partial
oferece e que você não consegue passar pelas lambdas?
Não há muito em termos de funcionalidade extra (mas, veja mais adiante) - e a legibilidade está nos olhos de quem vê.
A maioria das pessoas que estão familiarizadas com linguagens de programação funcionais (aquelas da família Lisp / Scheme em particular) parece gostar lambda
muito bem - eu digo "a maioria", definitivamente não todas, porque Guido e eu certamente estamos entre os "familiarizados" (etc ) ainda pense lambda
como uma anomalia desagradável em Python ...
Ele se arrependeu de ter aceitado o Python, enquanto planejava removê-lo do Python 3, como uma das "falhas do Python".
Eu o apoiei totalmente nisso. (Adoro lambda
no Scheme ... enquanto suas limitações em Python e a maneira estranha como ele simplesmente não faz ' com o resto do idioma, faça minha pele arrepiar).
Não é assim, no entanto, para as hordas de lambda
amantes - que encenaram uma das coisas mais próximas de uma rebelião já vista na história de Python, até Guido voltar atrás e decidir sair lambda
.
Várias adições possíveis a functools
(para fazer funções retornarem constantes, identidade, etc) não aconteceu (para evitar duplicar explicitamente mais lambda
funcionalidades), embora partial
tenha permanecido, é claro (não é uma duplicação total , nem é uma desagradável).
Lembre-se de que lambda
o corpo é limitado para ser uma expressão , por isso tem limitações. Por exemplo...:
>>> import functools
>>> f = functools.partial(int, base=2)
>>> f.args
()
>>> f.func
<type 'int'>
>>> f.keywords
{'base': 2}
>>>
functools.partial
A função retornada é decorada com atributos úteis para introspecção - a função que está agrupando e quais argumentos posicionais e nomeados ela fixa nela. Além disso, os argumentos nomeados podem ser substituídos de volta (a "correção" é, em certo sentido, a configuração dos padrões):
>>> f('23', base=10)
23
Então, como você vê, definitivamente não é tão simplista quanto lambda s: int(s, base=2)
! -)
Sim, você pode contorcer seu lambda para fornecer um pouco disso, por exemplo, para a substituição de palavras-chave,
>>> f = lambda s, **k: int(s, **dict({'base': 2}, **k))
mas espero sinceramente que mesmo o lambda
amante mais ardente não considere esse horror mais legível do que a partial
ligação! -). A parte "configuração do atributo" é ainda mais difícil, devido à limitação "do corpo como uma única expressão" do Python lambda
(além do fato de que a atribuição nunca poder fazer parte de uma expressão do Python) ... você acaba "fingindo atribuições dentro de uma expressão" estendendo a compreensão da lista muito além dos limites de design ...:
>>> f = [f for f in (lambda f: int(s, base=2),)
if setattr(f, 'keywords', {'base': 2}) is None][0]
Agora combine a substituibilidade dos argumentos nomeados, mais a configuração de três atributos, em uma única expressão e me diga o quão legível isso será ...!
functools.partial
mencionada o torna superior ao lambda. Talvez este seja o tópico de outro post, mas o que é que em um nível de design o incomoda tantolambda
?