Маленькі функції та lambda-вирази
Коли ви пишете програми у функціональному стилі, вам часто потрібні маленькі функції, які діють як предикати або об'єднують елементи певним чином.
Якщо існує вбудована функція Python або функція модуля, яка підходить, вам не потрібно визначати нову функцію взагалі:
stripped_lines = [line.strip() for line in lines]
existing_files = filter(os.path.exists, file_list)
Якщо потрібної вам функції не існує, вам потрібно її написати. Один зі способів написати маленькі функції — це використання виразу lambda
. lambda
приймає кілька параметрів та вираз, що об'єднує ці параметри, і створює анонімну функцію, яка повертає значення цього виразу:
adder = lambda x, y: x+y
print_assign = lambda name, value: name + '=' + str(value)
Альтернативою є просто використання оператора def
і визначення функції звичайним способом:
def adder(x, y):
return x + y
def print_assign(name, value):
return name + '=' + str(value)
Яка альтернатива є кращою? Це питання стилю; зазвичай я уникаю використання lambda
.
Одна з причин моєї переваги полягає в тому, що lambda
досить обмежена у функціях, які вона може визначити. Результат має бути обчислюваним як один вираз, що означає, що ви не можете використовувати багаторазові порівняння if... elif... else
або оператори try... except
. Якщо ви намагаєтеся зробити занадто багато у виразі lambda
, ви отримаєте надто складний вираз, який важко читати. Швидко, що робить наступний код? :
import functools
total = functools.reduce(lambda a, b: (0, a[1] + b[1]), items)[1]
Ви можете зрозуміти, але це займе час, щоб розплутати вираз і зрозуміти, що відбувається. Використання коротких вкладених операторів def
трохи покращує ситуацію:
import functools
def combine(a, b):
return 0, a[1] + b[1]
total = functools.reduce(combine, items)[1]
Але було б найкраще, якби я просто використовував цикл for
:
total = 0
for a, b in items:
total += b
Або вбудовану функцію sum
і генераторний вираз:
total = sum(b for a, b in items)
Багато використань functools.reduce
є зрозумілішими, коли їх записано як цикли for
.
Фредрік Лундг (Fredrik Lundh) запропонував наступний набір правил для рефакторингу використання lambda
:
- Напишіть
lambda
-функцію. - Напишіть коментар, що пояснює, що робить ця
lambda
-функція. - Вивчіть коментар деякий час і придумайте назву, яка втілює суть коментаря.
- Перетворіть
lambda
на операторdef
, використовуючи цю назву. - Видаліть коментар.
Мені дуже подобаються ці правила, але ви вільні не погоджуватись, чи цей стиль без використання lambda
є кращим.
Текст на цій сторінці є перекладом "Functional Programming HOWTO", автор: A. M. Kuchling. Інформація про копірайт: History and License.