Ответ 1
Я вижу некоторые моменты в вашем вопросе, пропуская их в порядке:
1. Могу ли я передать функцию как параметр кому-то?
Да:
def f(op, x, y):
return op(x, y)
def add(x, y):
return x + y
f(add, 10, 7) #gives 17
2. Как насчет операторов?
В отличие от схемы, операторы Python не являются функциями, поэтому вы не можете передавать их напрямую в качестве параметров. Вы можете сами создать функции обертки, или вы можете импортировать модуль operator из стандартной библиотеки.
import operator
operator.add(1, 2)
(lambda x,y : x+y)(1, 2)
Операторы, не являющиеся реальными функциями, в большинстве случаев немного печальны, но по крайней мере Python дает нам скованные сравнения, такие как 10 <= x < 100
в обмене...
3. Так в чем же разница между Python и Scheme?
В общем смысле функции в Python столь же сильны, как и функции на Схеме, однако есть некоторые вещи, которые следует отметить:
Ключевое слово lambda ограничено
У вас может быть только одно выражение как тело функции
f = lambda x, y: x + y
Поскольку в Python есть куча вещей, которые являются операторами, а не выражениями (назначениями, 2.x print
,...), вам часто приходится возвращаться к именованным функциям.
Есть замыкания
def make_printer(msg):
def printer():
print msg
return printer
printer('a message')()
Но мутирующие переменные в них - это боль
Это не работает. Он пытается связать новый n для внутренней функции, а не использовать внешний
def make_counter(n):
def inc():
n = n + 1
return n
return inc
новое 3.x нелокальное ключевое слово
def make_counter(n):
def inc():
nonlocal n
n = n + 1
return n
return inc
обходной путь w/изменяемые объекты
def make_counter(n):
nw = [n]
def inc():
nw[0] = nw[0] + 1
return nw[0]
return inc
Объекты вместо закрытий. Использует магический метод __call__
, чтобы притворяться его функцией
class Counter:
def __init__(self, n):
self.n = n
def __call__(self):
self.n += 1
return self.n