Based of this answer, chcę stworzyć one line tree jako część innej klasy jak tak:One linię realizacja drzewo
self._tree = collections.defaultdict(lambda: self._tree)
będę potrzebował, aby umożliwić użytkownikom powiedział klasa dodać elementy ścieżki do drzewa i uruchomić niektóre wywołanie zwrotne rozpoczynające się od najniższego poziomu drzewa. Mój naiwny realizacja podnosi błąd, gdy biegnę pytest
:
def _add(self, tree, path):
for node in path:
tree = tree[node]
def _run(self, tree, callback):
for key in tree.keys():
callback(tree[key]) # !!! Recursion detected (same locals & position)
self._run(key)
Ten kod działa IFF drzewo jest zdefiniowany jako
def tree():
return collections.defaultdict(tree)
self._tree = tree()
Dlaczego moje naiwne podejście nie działa z wyrażenia lambda?
⚠ The Zen of Python stwierdza, że
Proste jest lepsze niż skomplikowane.
Jednokresowa lambda tworzy kompleks kodu, w którym znajduje się simpler implementation. Dlatego jednolinijkowa lambda nie powinna być używana w kodzie produkcyjnym. Pozostawiam jednak to pytanie tutaj dla zainteresowania akademickiego.
Metoda przekazana do 'defaultdict' musi utworzyć nową instancję, a nie odwołanie do istniejącego obiektu. W twoim przypadku 'drzewo' jest metodą, która zwraca nowe' defaultdict (drzewo) ', ale twoja jedna linijka to lambda, która zwraca oryginalną instancję' self._tree' 'defaultdict (lambda: etc.)' – PaulMcG
@ PaulMcGuire: Więc dlaczego 'd = collections.defaultdict (lambda: d); d ['foo'] ['bar'] 'wydaje się działać dobrze pomimo brzydkiego podczas drukowania? – Sardathrion
Odpowiedź Kevina i komentarz Tadhga McDonald-Jensena ilustrują niewłaściwą rekurencję w jednoliniowym podejściu lambda. – PaulMcG