RE Python folgt diesem Prinzip nicht. Im Allgemeinen folgt es dem Prinzip. Einfaches Beispiel:
>>> x = ['foo']
>>> x
['foo']
>>> x = (lambda: ['foo'])()
>>> x
['foo']
Python definiert jedoch Ausdrücke und Anweisungen separat. Da if
Verzweigungen, while
Schleifen, destruktive Zuweisungen und andere Anweisungen in lambda
Ausdrücken überhaupt nicht verwendet werden können , gilt der Buchstabe des Tennent-Prinzips nicht für sie. Selbst wenn Sie sich darauf beschränken, nur Python-Ausdrücke zu verwenden, erhalten Sie immer noch ein Turing-Gesamtsystem. Ich sehe das also nicht als Verstoß gegen das Prinzip; oder vielmehr, wenn es gegen das Prinzip verstößt, kann möglicherweise keine Sprache, die Aussagen und Ausdrücke separat definiert, dem Prinzip entsprechen.
Auch wenn der Körper des lambda
Ausdrucks eine Stapelverfolgung aufzeichnet oder eine andere Introspektion in der VM durchführt, kann dies zu Unterschieden führen. Meiner Meinung nach sollte dies jedoch nicht als Verstoß gewertet werden. Wenn expr
und (lambda: expr)()
notwendigerweise zu demselben Bytecode kompiliert wird, dann betrifft das Prinzip wirklich Compiler, nicht Semantik; Wenn sie sich jedoch zu einem anderen Bytecode kompilieren lassen, sollten wir nicht erwarten, dass der VM-Status in jedem Fall identisch ist.
Eine Überraschung ist bei der Verwendung der Verständnissyntax zu erwarten, auch wenn dies meiner Meinung nach keine Verletzung des Tennent-Prinzips darstellt. Beispiel:
>>> [x for x in xrange(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [f() for f in [lambda: x for x in xrange(10)]] # surprise!
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
>>> # application of Tennent principle to first expression
... [(lambda: x)() for x in xrange(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [f() for f in [(lambda x: lambda: x)(x) for x in xrange(10)]] # force-rebind x
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> map(lambda f:f(), map(lambda x: lambda: x, xrange(10))) # no issue with this form
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Die Überraschung ist das Ergebnis der Definition des Listenverständnisses. Das obige "Überraschungs" -Verständnis entspricht diesem Code:
>>> result = []
>>> for x in xrange(10):
... # the same, mutable, variable x is used each time
... result.append(lambda: x)
...
>>> r2 = []
>>> for f in result:
... r2.append(f())
...
>>> r2
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
So gesehen ist das obige "Überraschungs" -Verständnis weniger überraschend und keine Verletzung des Tennent-Prinzips.