2016-04-21 4 views
0
def add_info_extractor(self, ie): 
    """Add an InfoExtractor object to the end of the list.""" 
    self._ies.append(ie) 
    if not isinstance(ie, type): 
     self._ies_instances[ie.ie_key()] = ie 
     ie.set_downloader(self) 

def get_info_extractor(self, ie_key): 
    """ 
    Get an instance of an IE with name ie_key, it will try to get one from 
    the _ies list, if there's no instance it will create a new one and add 
    it to the extractor list. 
    """ 
    ie = self._ies_instances.get(ie_key) 
    if ie is None: 
     ie = get_info_extractor(ie_key)() 
     self.add_info_extractor(ie) 
    return ie 

Das Folgende stammt aus einem populären Python Repo, dem Youtube-dl. In dem Bestreben, ein besserer Programmierer zu werden, gehe ich quer durch diesen Abschnitt und habe Schwierigkeiten, es zu verstehen.Wie funktioniert dieser bestimmte Codeabschnitt?

Insbesondere die letzte Methode und wie es keine unendliche Rekursion eingeben, wenn der ie_key nicht in der Liste gefunden wird.

Sowie der isinstance Vergleich in der ersten Methode.

Ich verstehe die normale Implementierung ist etwas für die Wirkung von: isinstance ('Hallo', str), aber wie kann Typ() ein Typ sein? Außerdem: Was ist der Sinn, ein Objekt mit einem Typ zu vergleichen?

+0

Ich würde vermuten, dass _ies_instances ein dict ist, und hat irgendwann etwas wie 'self._ies_intances [None] = var' – JETM

+0

Es gibt endlose Rekursion ... – Bharel

Antwort

1

Dies könnte sicherlich eine unendliche Rekursion verursachen. Zwischen rekursiven Aufrufen scheinen self._ies_instances keine Aktualisierungen zu passieren, und da die Rekursion von diesem Fall abhängt, wird sie fortgesetzt.

Vielleicht ist dies ein Fehler, aber der Code hatte nie eine Situation, wenn ie_key nicht im Wörterbuch ist?

Wie für Ihre Verwirrung mit type, ist es ein Ergebnis von Python Metaclasses (ein toller gelesen). type fungiert sowohl als eine "Funktion", um den Typ eines Objekts als auch eine Klasse zurückzugeben, um einen neuen Typ zu erstellen (wenn mit mehr Argumente aufgerufen).

Ein Grund möchten Sie vielleicht überprüfen, um zu sehen, ob etwas eine Instanz von type ist zu sehen, ob etwas ein Metaklasse ist:

>>> isinstance(1, type) 
False 
>>> isinstance("", type) 
False 
>>> isinstance({}, type) 
False 
>>> isinstance((), type) 
False 
>>> type(object) == type 
True 
>>> isinstance(object, type) 
True 
>>> isinstance(object(), type) 
False 
>>> class a(): pass 
... 
>>> isinstance(a, type) 
False 
>>> isinstance(a(), type) 
False 

Wie object ist die ‚Basis für alle Klassen neuen Stils‘ (docs), fungiert auch als Metaklasse (wie oben gezeigt).

1

Ich glaube, der Grund, warum diese unendliche Rekursion vermeidet, ist, dass es nie tatsächlich recurses überhaupt! Schauen Sie genau hin:

def get_info_extractor(self, ie_key): 
    ... 
    ie = get_info_extractor(ie_key)() 

Beachten Sie, dass die get_info_extractor deren Definition wir lesen ein Verfahren ist, und es ruft eine nicht-Methode Funktion, die gerade geschieht so auch get_info_extractor genannt werden, und so ist es nicht selbst anrufen, und deshalb gibt es keine Rekursion.

Verwandte Themen