Wywołania rekurencyjne w generatorze

0

Jest to kawałek kodu z książki Python.Wprowadzenie, którego nie potrafię zrozumieć. Załóżmy, że mam instancję klasy A, która jest podklasą klas B i C. Rozumiem to w ten sposób, że przekazujemy tu klasę A, która w generatorze wywołuje rekurencje najpierw klasy nadrzędnej B, która dalej wywołuje klasę object, która zwraca napis dla object, następnie zwracany jest napis dla B. Teraz wywoływana jest klasa C i następnie object (zwracany jest object i C), a dalej wykonywany jest kod dla klasy A, gdzie metoda join wywołuje automatycznie wszystkie stany po kolei czyli object, B, object, C, A. Jednak działa to odwrotnie czyli najpierw jest napis klasy A, potem B, object, C i object. Czy jednak działa to tak, że generator jest tworzony, i rekurencja jest wywoływana dopiero podczas wywołania generatora metodą join. Byłbym bardzo wdzięczny, gdyby ktoś wytłumaczył co się po kolei dzieje(step by step).

def __listclass(self, aClass, indent):
		dots = '.' * indent
		if aClass in self.__visited:
			return '\n{0}<Klasa {1}:, adres {2}: (patrz wyżej)>\n'.format(dots,
																	aClass.__name__,
																	id(aClass))
		else:
			self.__visited[aClass] = True
			genabove = (self.__listclass(c, indent+4) for c in aClass.__bases__)
			return '\n{0}<Klasa {1}:, adres {2}:\n{3}{4}{5}>\n'.format(dots,	
																	 aClass.__name__,
																	 id(aClass),
																	 self.__attrnames(aClass, indent),
																     ''.join(genabove),
																	 dots)
0

Kod brzydki i nie do końca cokolwiek wnosi do nauki Pythona ;)

Zauważ, że wchodzac po raz pierwszy do funkcji (odpalane z A) wchodzisz do else: i tam pobierasz do getabove dla klas bazowych (tu jest wywoływana rekurencja. Jeżeli B lub C mają klasy bazowe to getabove zostanie rozszerzone itp). Ale jeszcze nie drukujesz tego nigdzie i dopiero potem masz return w którym najpierw wypisujesz A i na końcu robisz join na getabove.

0

To jeśli dobrze rozumiem do generatora zwracane są wyniki rekurencji zaczynając od tej najgłębiej. Czyli gdyby B miała klasę bazową(D), to generator powinien zwrócić najpierw napis dla D potem dla B, jednak drukowane są w kolejności wywoływania. Nie rozumiem czemu zwracany jest napis dla B skoro zanim zostanie zwrócony to rekurencja wejdzie do D i dopiero tu po raz pierwszy zadziała return, potem kod wróci w miejsce wykonania rekurencji dla B i zwróci B.

1 użytkowników online, w tym zalogowanych: 0, gości: 1