2016-08-01 21 views
1

Ich bin derzeit etwas ähnliches auf diese Frage zu replizieren: python switch by class name?Duck Typing und Fremdkörper

Ich habe eine for-Schleife, dass iteriert über einen Satz von Objekten und sortiert sie nach ihrer Art, in eine von mehreren Listen.

for obj in list_of_things: 
    if isinstance(obj, Class1): 
     class1list.append(obj) 
    if isinstance(obj, Class2): 
     class2list.append(obj) 

usw. für mehrere andere Klassen. Die Anwendung ist so etwas wie ein ORM - Daten aus jeder Klasse werden extrahiert und in eine Datenbank geschrieben, und jede Klasse hat andere Daten zum Extrahieren. Darüber hinaus ist es erforderlich, dass alle Instanzen von Class1 von dem ORM vor Instanzen von Class2 verarbeitet werden.

Schließlich sind Class1 und Class2 nicht meins - sie sind die Ausgabe einer API, die ich verwende, also habe ich keine Möglichkeit, sie zu ändern, wie in der vorherigen Frage vorgeschlagen (wie, eine serialize schreiben() Methode, die die Daten ablegt, die ich in jeder Klasse benötige). Ich stelle eine Anfrage an die API für einige Objekte, und es überflutet mich mit Objekten verschiedener Art, von denen ich jeweils verschiedene Daten extrahieren muss.

Gibt es eine pythonische Art, dies zu tun? Dieser Ansatz entspricht dem Bedürfnis, aber es schmerzt meine Augen und ich würde gerne einen besseren Weg lernen. Ich bin noch ziemlich neu bei Python.

Antwort

0

Ein anderer Ansatz, abhängig von Ihren Besonderheiten, könnte die Tatsache nutzen, dass der Typ type unveränderlich ist und somit als Wörterbuchschlüssel verwendet werden kann.

So könnte man so etwas wie:

from collections import defaultdict 

list_of_things = [2, 3, "Some", "String"] 

obj_map = defaultdict(list)  
for obj in list_of_things: 
    obj_map[type(obj)].append(obj) 

print(obj_map) 

Ausgang:

defaultdict(<type 'list'>, { 
    <type 'int'>: [2, 3], 
    <type 'str'>: ['Some', 'String'] 
}) 

Die Idee dabei ist, dass Sie nicht eine ganze Reihe von if isinstance Tests schreiben müssen, die Sie gerade „Gruppe nach "jedem Objekttyp.

Sie können die Werte des Wörterbuchs zugreifen, indem Sie die Klassennamen als Schlüssel:

print(obj_map[int]) # [2, 3] 
+0

ich darüber nachgedacht, aber mein Verständnis ist, dass Typ() keine Unterklasse Beziehungen respektieren, so dass, wenn die dritte Party-API-Unterklassen Class1, aber ich möchte die Unterklassen als Instanzen von Class1 behandeln, wäre es nicht möglich. Im Moment weiß ich zufällig, dass es keine Unterklassen gibt, die ich bekommen werde, aber bin ich der Meinung, dass die Verwendung von type() gegenüber isinstance() das Ergebnis möglicherweise so verändern könnte? –

+0

@JustinPalpant Sie haben Recht, die Unterklassen * würden unter verschiedenen Schlüsseln hinzugefügt werden. Du könntest eine Introspektion mit 'type (obj) .__ base__' machen, aber ich sehe nur, dass es schnell hässlich wird. Wenn jedoch das Hinzufügen von Unterklasseninstanzen unter verschiedenen Schlüsseln zulässig ist, können Sie Instanzen einer gegebenen Klasse und ihrer Unterklassen immer mit 'issubclass()' entfernen. – jedwards

+0

Ich wusste nichts über 'issubclass()', das klingt, als könnte es gefüllt werden die letzte Nische. Ich stimme zu, dass "type (obj) .__ base__" so aussieht, als könnte es chaotisch werden. Ich werde dies als akzeptiert markieren. –