Ich sehe einige Punkte in Ihrer Frage, gehen wir sie der Reihe nach durch:
1. Kann ich eine Funktion als Parameter an jemanden übergeben?
Ja:
def f(op, x, y):
return op(x, y)
def add(x, y):
return x + y
f(add, 10, 7) #gives 17
2. Was ist dann mit den Betreibern?
Im Gegensatz zu Schema sind Python-Operatoren keine Funktionen, so dass Sie sie nicht direkt als Parameter übergeben können. Sie können die Wrapper-Funktionen entweder selbst erstellen oder Sie können die Betreiber Modul aus der Standardbibliothek.
import operator
operator.add(1, 2)
(lambda x,y : x+y)(1, 2)
Dass Operatoren keine echten Funktionen sind, ist in den meisten Fällen ein bisschen traurig, aber wenigstens bietet Python uns verkettete Vergleiche wie 10 <= x < 100
im Gegenzug...
3. Was ist also der Unterschied zwischen Python und Scheme?
Im Allgemeinen sind die Funktionen in Python genauso mächtig wie die Funktionen in Scheme, aber es gibt einige Dinge zu beachten:
Das Schlüsselwort lambda ist begrenzt
Sie können nur einen einzigen Ausdruck als Funktionskörper verwenden
f = lambda x, y: x + y
Da es in Python eine Reihe von Dingen gibt, die Anweisungen und keine Ausdrücke sind (Zuweisungen, die 2.x print
, ...), müssen Sie stattdessen oft auf benannte Funktionen zurückgreifen.
Es gibt Schließungen
def make_printer(msg):
def printer():
print msg
return printer
printer('a message')()
Aber das Mutieren von Variablen in ihnen ist mühsam
Das klappt nicht. Es wird versucht, ein neues n für die innere Funktion zu binden, anstatt die äußere zu verwenden
def make_counter(n):
def inc():
n = n + 1
return n
return inc
neues 3.x nicht-lokales Schlüsselwort
def make_counter(n):
def inc():
nonlocal n
n = n + 1
return n
return inc
Umgehung mit veränderbaren Objekten
def make_counter(n):
nw = [n]
def inc():
nw[0] = nw[0] + 1
return nw[0]
return inc
Objekte anstelle von Verschlüssen. Verwendet die magische __call__
Methode, um so zu tun, als sei sie eine Funktion
class Counter:
def __init__(self, n):
self.n = n
def __call__(self):
self.n += 1
return self.n