2014-04-10 12 views
5

Herumspielen mit Bäumen, ich über dieses Verhalten gestolpert:Leere Generator

def descendants (self): 
    return #or "pass" or "42" 

kehrt offenbar None.

Auf der anderen Seite:

def descendants (self): 
    return 
    yield 42 

gibt einen Generator, der nichts (eigentlich das Verhalten, das ich brauchte für Blattknoten) ergibt.

Kann mir jemand erklären, was hier unter der Haube passiert?

Sollte nicht der yield 42 Code nicht erreichbar sein? (Ich denke, die Entscheidung, ob eine Funktion ein Generator oder eine "normale" Funktion ist, wird zur Kompilierzeit gemacht, abhängig davon, ob sie eine oder mehrere yield Anweisungen enthält, ob sie erreichbar sind oder nicht. Aber das ist nur eine Einstellung im Dunkeln .)

Der Kontext ist der folgende: Ich habe Bäume und jeder Knoten ist entweder ein Baum oder ein Blatt. Jetzt möchte ich alle Nachkommen eines Knotens erzeugen:

class Leaf (Node): 
    @property 
    def descendants (self): 
     return 
     yield 42 

class Tree (Node): 
    @property 
    def descendants (self): 
     for child in self.children: 
      yield child 
      yield from child.descendants 
+0

Ich normalerweise nur 'return()', da es sich ungefähr wie ein leerer Generator verhält. – U2EF1

Antwort

4

Wie ich es verstehe, die yield Schlüsselwort innerhalb einer Funktion zur Compile-Zeit erkannt wird. Das Ergebnis ist, dass sich die Funktion nicht mehr wie eine normale Funktion verhält. Wenn eine Funktion mit einem Yield-Schlüsselwort aufgerufen wird, gibt die Funktion IMMEDIATELY ein träges Generatorobjekt zurück, das gemäß der definierten Funktion Variablen erzeugt, die benötigt werden. Der Code in Ihrer Funktion wird nur ausgeführt, wenn der Generator durchlaufen wird.

es mehr erklärte kurz und bündig here.

So descendants genannt wird, und da das yield Schlüsselwort in der Funktion vorhanden ist, wird ein Generator-Objekt sofort zurückgegeben. Seit descendants sofort return s, aber der Generator liefert keine Werte - aber es ist definitiv immer noch ein Generator.

+0

Danke für den Link. Ich habe die verknüpfte Frage gefunden, konnte jedoch nicht zu der Antwort blättern, die Sie verknüpft haben. Lass mich das ein bisschen verdauen. – Hyperboreus

+0

Haben Sie irgendwelche Links zu Sprachdokumenten, da dies nichts aussagt: https://docs.python.org/3.4/tutorial/classes.html#generators – Hyperboreus

+0

@JesseMu +1 Sie haben saubere und genaue Erklärung gemacht . –