#python #lambda #inspect
#python #лямбда #Осмотр
Вопрос:
Для какой-то цели мне нужна церковная кодировка чисел, поэтому я определяю числа следующим образом:
# Let's define zero
zero = lambda f: lambda x: x
# A successor function
successor = lambda n: lambda f: lambda x: f(n(f)(x))
# Now I can define any number inductively/recursively
one = successor(zero)
two = successor(successor(zero))
Теперь, если я попытаюсь напечатать источник one
, two
, и т.д., Полные выражения не будут приведены к их обычным формам:
import inspect;
print(inspect.getsource(zero))
print(inspect.getsource(one))
print(inspect.getsource(two))
Вывод:
zero = lambda f: lambda x: x
succ = lambda n: lambda f: lambda x: n(f)(x)
succ = lambda n: lambda f: lambda x: n(f)(x)
Как я могу увидеть уменьшенную форму, где тело самого внутреннего лямбда-выражения для one
и two
сводится к нормализованной форме (вычисляется?), Т.Е. Я могу определить разницу между сокращенными выражениями one
и two
.
В качестве ссылки эквивалентная форма one
и two
может быть следующей:
zero = lambda f: lambda x: x
one = lambda f: lambda x: f(x)
two = lambda f: lambda x: f(f(x))
Но я не могу получить такое же различие от inspect.getsource
. Конечно, мне не нужна дословная эквивалентность, но что-то, что все еще способно показывать разные уровни вложенности в one
и two
.
Комментарии:
1. В Python нет отложенной оценки . Вы можете воспроизвести отложенную оценку с помощью итераторов / генераторов. Но Python с нетерпением оценивается. В любом случае,
inspect.getsource
это ничего вам не даст, оно опирается на фактический исходный код.
Ответ №1:
Для этого конкретного случая вы можете передать новую лямбда-функцию в качестве аргумента one
or two
, которая возвращает строку с правильным уровнем стекирования. Однако это не дает вам форму лямбда-входов ( lambda f: lambda x:
).
zero(lambda x: f'f({x})')('x')
# returns:
'x'
one(lambda x: f'f({x})')('x')
# returns:
'f(x)'
two(lambda x: f'f({x})')('x')
# returns:
'f(f(x))'