Seite 1 von 1

Komische Frage zur Erzeugung von Instanzen

Verfasst: Dienstag 5. April 2005, 22:23
von leoel
Hallo!

Ich hab da ein Problem, und ich weiss nicht, wie man das möglichst elegant lösen kann.

Die ganze Sache ist ein bisschen kompliziert, also beschränke ich mich auf das Wesentliche:

Ich habe eine Liste von Namen (Strings) die ich aufgrund eines internen Mappings zu bestimmten Klassen zuordne, soweit so gut

Was ich jetzt suche, ist eine Möglichkeit aufgrund eines Strings eine Instanz der entsprechenden Klasse (inkl. Konstruktor-Argumente) zu erzeugen.

so eine Art Funktion

Code: Alles auswählen

myObj = getInstanceByName("class_name", args)
Ob jetzt "args" eine Liste oder Tupel ist, ist ziemlich egal

Wisst Ihr eine Möglichkeit, wie ich das am besten angehen könnte?

Am besten wäre eine Möglichkeit mit

Code: Alles auswählen

myObj = getInstanceByName("<package>.<package>.<modul>.<class>", args)

Vielen Dank,
Leo

Verfasst: Mittwoch 6. April 2005, 09:40
von fs111

Code: Alles auswählen

def factory(name, *args):
    return apply(globals()[name], args)

class A:
    def __init__(self, *args):
        self.args = args

a = A((1,2,3,4))

b = factory('A', (1,2,3,4))

Das sollte gehen.

HTH

fs111

Verfasst: Mittwoch 6. April 2005, 12:23
von leoel
Danke, werde ich ausprobieren.

Verfasst: Mittwoch 6. April 2005, 21:42
von BlackJack
Statt ``apply`` kann man seit Python 2.3 auch die erweiterte Aufrufsyntax benutzen, in der man eine (Argument)Liste (bzw. "Iterable" im Allgemeinen) beim Aufruf automatisch "entpacken" kann:

Code: Alles auswählen

def call_by_name(name, *args):
    return globals()[name](*args)

Verfasst: Mittwoch 6. April 2005, 22:09
von leoel
Hallo!

@BlackJack: Du bist mir grad ein paar Minuten zuvorgekommen... ;-)

d.h. ausprobiert, codiert, eingewählt und siehe da, dieselbe Lösung..

Auf das bin also ich gekommen:

Code: Alles auswählen

class A(object):
    def __init__(self, v1, v2):
        self.v1 = v1
        self.v2 = v2
    
    def testOutput(self):
        print "V1:", self.v1
        print "V2:", self.v2

def factory(name, value):
    return globals()[name](*value)


T = factory('A', ('eins', 'zwei'))
T.testOutput()
Identer[1] kann die Lösung wohl nicht sein...

Wie war das nochmals: "There should be one obvious way to do it..."

Jedenfalls vielen Dank, das Problem hat ganz schön genagt..

liebe Grüße,
Leo

[1] genau so schlimm wie "optimaler"