Различия между functools.partial и аналогичной лямбдой?
В Python предположим, что у меня есть функция f
, которую я хочу передать с некоторыми вторичными аргументами (предположим для простоты, что это только первый аргумент, который остается переменным).
В чем разница между этими двумя способами (если есть)?
# Assume secondary_args and secondary_kwargs have been defined
import functools
g1 = functools.partial(f, *secondary_args, **secondary_kwargs)
g2 = lambda x: f(x, *secondary_args, **secondary_kwargs)
На странице doc для partial
, например, есть эта цитата:
partial
объекты, определенные в классах, ведут себя как статические методы и не преобразуются в связанные методы при просмотре атрибутов экземпляра.
Может ли этот лямбда-метод страдать от этого, если используется для создания метода класса из аргументов, предоставленных классу (либо в конструкторе, либо через функцию позже)?
Ответы
Ответ 1
-
Лямбда-функция имеет тот же тип, что и стандартная функция, поэтому она будет вести себя как метод экземпляра.
-
Объект partial
в вашем примере можно вызвать следующим образом:
g1(x, y, z)
приводящий к этому вызову (недействительный синтаксис Python, но вы получаете идею):
f(*secondary_args, x, y, z, **secondary_kwargs)
Лямбда принимает только один аргумент и использует другой порядок аргументов. (Конечно, оба эти различия могут быть преодолены - я просто отвечаю на то, что различия между двумя версиями вы дали.)
-
Выполнение объекта partial
выполняется немного быстрее, чем выполнение эквивалентного lambda
.
Ответ 2
Я считаю, что предмет метода класса применим только к функциям, назначенным во время определения класса. Функции, назначенные позже, не обрабатываются специально.
Кроме этого, я лично одобряю лямбда, поскольку они более распространены и, следовательно, делают код более понятным.
class Foo(object):
def __init__(self, base):
self.int = lambda x:int(x, base)
print Foo(4).int('11')
Ответ 3
Да, lambda
будет "страдать" от этого. partial
не имеет этой проблемы, потому что это объект с перегруженным оператором вызова, а не с реальной функцией.
Но использование лямбда, подобного этому в определении класса, является просто неправильным использованием.
Ответ 4
Частичные части не только на 20% быстрее, чем эквивалентные лямбда, как уже сказано, но они сохраняют прямой рефлекс, к которому они относятся. В то время как в lambdas эта функция "обрывается" внутри тела функции.
= > Если вам нужно решить проблему отсрочки оценки одной функции до тех пор, пока не будут известны все аргументы, используйте частичные. У вас будут лучшие методы интроспекции по сравнению с похоронами вызовов в анонимные функции, т.е. Lambdas.