Предположим, у вас есть структура графа. Соседи узла могут быть получены дорогостоящей операцией get_neighbor(server, node)
(например, извлечением чего-либо из Интернета), которая требует административного параметра server
. Ваша задача - найти путь от заданного начального узла.
У вас уже есть подпрограмма поиска, которая достаточно умна, чтобы вычислять окрестности по требованию. Но вы не можете изменять интерфейс этой подпрограммы, так как она используется где-то еще. В частности, вы не можете ввести административный параметр:
def search(p, node, todo, graph, visited):
visited[n] = True
if p(n):
return n
# Note, we evaluate the neighborship relation on demand
for n in graph[node]():
if n not in visited:
todo.append(n)
if len(todo) == 0:
return None
next = todo.pop(0)
return search(p, next, todo, graph, visited)
Мы могли бы использовать простые символы (лямбды) для оценки отношения соседства только при необходимости:
for node in all_nodes():
tree[node] = (lambda node : lambda : get_neighbor(server, node))(node)
(необходима двойная лямбда) для принудительного сбора значений.)
Это должно работать нормально для одной оценки поиска, поскольку каждая дорогостоящая операция выполняется не более одного раза. Но для повторных поисков по одному и тому же графику одни и те же запросы могут повторяться. Поэтому в идеале возвращаемая лямбда должна кешировать свое значение, т. Е. Становиться фактически ленивым.
Как создать такой thunk наиболее идиоматическим образом c в python, предпочтительно без дополнительных зависимостей?