Я получаю это предупреждение pep8 всякий раз, когда я использую лямбда-выражения. Не рекомендуется ли лямбда-выражения? Если не так?
E731 не назначают лямбда-выражение, используйте def
Ответ 1
Рекомендация в PEP-8, в которой вы работаете:
Всегда используйте инструкцию def вместо инструкции присваивания, которая связывает лямбда-выражение непосредственно с именем.
Да:
<Не p > Нет:def f(x): return 2*x
f = lambda x: 2*x
Первая форма означает, что имя получающейся функциональный объект - это скорее "f", а не общий ". Это более полезно для отслеживания и строковых представлений в Генеральная. Использование оператора присваивания исключает единственную выгода выражения lambda может предложить более явное определение def (т.е. что он может быть встроен в большее выражение)
Назначение lambdas для имен в основном просто дублирует функциональность def
- и в целом лучше всего сделать что-то одним способом, чтобы избежать путаницы и повысить ясность.
Допустимым вариантом использования лямбда является то, где вы хотите использовать функцию без ее назначения, например:
sorted(players, key=lambda player: player.rank)
Ответ 2
Вот история, у меня была простая лямбда-функция, которую я использовал дважды.
a = map(lambda x : x + offset, simple_list)
b = map(lambda x : x + offset, another_simple_list)
Это просто для представления, я столкнулся с двумя разными версиями этого.
Теперь, чтобы сохранить вещи СУХОЙ, я начинаю использовать эту обычную лямбду.
f = lambda x : x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
В этот момент мой контролер качества кода жалуется, что lambda является именованной функцией, поэтому я конвертирую ее в функцию.
def f(x):
return x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
Теперь контролер жалуется, что функция должна быть ограничена одной пустой строкой до и после.
def f(x):
return x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
Здесь мы имеем теперь 6 строк кода вместо исходных 2 строк без увеличения читаемости и без увеличения pythonic. На этом этапе программа проверки кода жалуется на функцию, не имеющую докстрон.
По-моему, это правило лучше избегать и нарушать, когда это имеет смысл, используйте свое мнение.
Ответ 3
Lattyware абсолютно прав: в основном PEP-8 хочет, чтобы вы избегали таких вещей, как
f = lambda x: 2 * x
и вместо этого используйте
def f(x):
return 2 * x
Однако, как описано в недавнем bugreport (август 2014 г.), теперь выполняются следующие утверждения:
a.f = lambda x: 2 * x
a["f"] = lambda x: 2 * x
Так как моя контрольная панель PEP-8 не реализует это правильно, я пока не выключил E731.
Ответ 4
Я также столкнулся с ситуацией, в которой было даже невозможно использовать функцию def (ined).
class SomeClass(object):
# pep-8 does not allow this
f = lambda x: x + 1 # NOQA
def not_reachable(self, x):
return x + 1
@staticmethod
def also_not_reachable(x):
return x + 1
@classmethod
def also_not_reachable(cls, x):
return x + 1
some_mapping = {
'object1': {'name': "Object 1", 'func': f},
'object2': {'name': "Object 2", 'func': some_other_func},
}
В этом случае я действительно хотел сделать сопоставление, принадлежащее классу. Некоторым объектам в карте нужна одна и та же функция. Было бы нелогично ставить названную функцию вне класса. Я не нашел способ ссылаться на метод (staticmethod, classmethod или normal) изнутри тела класса. SomeClass еще не существует, когда код запущен. Так что ссылаться на это из класса тоже невозможно.
Ответ 5
Lambdas может использоваться для ленивых оценок, таким образом откладывая некоторые дорогостоящие операции, пока их результаты не понадобятся.
Я просто столкнулся с одним случаем (по проблеме конкуренции/практики с кодом), где я вычислял относительно дорогие функции pow() (относительно дорого, так как вход состоял из полумиллиона тестовых случаев) для 3 разных случаев и некоторых комбинаций из 3 случаев. Для ясности кода я бы вычислил все 3 случая, а затем вернул комбинацию из 3, которые были действительно необходимы для текущего запроса.
К сожалению, это привело к созданию TLE ( "превышение времени" ) на определенных входах.
Используя lambdas для отсрочки дорогостоящих операций pow(), я смог разрешить проблемы TLE, поскольку на самом деле были вызваны только вычисления, имеющие отношение к текущему запросу.
Итак, я думаю, что это случай, когда предупреждение E731 действительно не применимо и должно быть отключено..