Seite 1 von 1

dynamische Instanzierung?

Verfasst: Freitag 23. März 2007, 12:44
von aga
Hi!

Bitte um Verständnis, da ich noch immer Python Anfänger bin..
Ich möchte folgendes erreichen: zur Laufzeit habe ich den Modul- und Klassennamen (als strings) und möchte daraus eine Instanz der Klasse bekommen - wie geht das?
Btw, gibt's in Python so was wie Reflection in Java?

danke im voraus

Re: dynamische Instanzierung?

Verfasst: Freitag 23. März 2007, 13:01
von gerold
Hallo aga!

Eine Möglichkeit wäre ``locals()``:

Code: Alles auswählen

>>> class Hallo:
...     pass
...     
>>> h = locals()["Hallo"]()
>>> h
<__main__.Hallo instance at 0x01AA4C38>
>>>

mfg
Gerold
:-)

Verfasst: Freitag 23. März 2007, 13:52
von birkenfeld
Mit den locals() fällt man nur innerhalb von Funktionen auf die Schnauze.

Verfasst: Freitag 23. März 2007, 14:03
von gerold
birkenfeld hat geschrieben:Mit den locals() fällt man nur innerhalb von Funktionen auf die Schnauze.
Hallo birkenfeld!

Manchmal verstehe ich dich nicht. Warum schreibst du nur "das geht nicht" und zeigst keine Lösung auf?

@aga: Wenn ``locals()`` nicht funktioniert, dann könnte ``globals()`` funktionieren. Wenn du die Klassen in ein anderes Modul geschrieben hast, dann musst du das Modul vorher importieren und statt ``globals()`` mit ``getattr(<modulobjekt>, "Klassenname")`` an die Sache heran gehen.

mfg
Gerold
:-)

Verfasst: Freitag 23. März 2007, 14:06
von mitsuhiko
locals() ist langsam und funktioniert nur im globalen Scope. aga hat aber weder einen scope noch klingt locals() nach einer eleganten Lösung. Wenn er Klassen und Modulnamen hat kann er ja das machen:

Code: Alles auswählen

def create_instance(*args, **kwargs):
    module, class_ = args[:2]
    cls = getattr(__import__(module, None, None, ['']), class_)
    return cls(*args[2:], **kwargs)

foo = create_instance("my.module", "MyClass", "some", "arguments", keywordargumets="too")

Verfasst: Freitag 23. März 2007, 14:50
von gerold
blackbird hat geschrieben:locals() ist langsam
Hi blackbird!

Das ist interessant. Ich verwende locals() ziemlich gerne. Durch was könnte ich es ersetzen, ohne jede Variable einzeln angreifen zu müssen, oder alles schon vorab in ein Dictionary zu legen? Warum ist locals() langsam?

Nur so als Beispiel :

Code: Alles auswählen

vorname = "Max"
nachname = "Mustermann
alter = 10

print "ID: %(nachname)s_%(vorname)s: %(vorname)s %(nachname)s ist %(alter)i Jahre alt" % locals()
mfg
Gerold
:-)

Verfasst: Freitag 23. März 2007, 15:32
von birkenfeld
gerold hat geschrieben:Manchmal verstehe ich dich nicht. Warum schreibst du nur "das geht nicht" und zeigst keine Lösung auf?
Weil ich nicht so viel Zeit habe, ständig so viel zu schreiben -- außerdem könnt ihr das viel besser.

IMO ist locals() an sich ja ein guter Hinweis, und man kann als engagierter Programmierer auch selbst herausfinden, warum locals() hier nicht passt und dass es auch globals() gibt. So schlecht ist die Doku ja nicht.

Re: dynamische Instanzierung?

Verfasst: Freitag 23. März 2007, 17:14
von Leonidas
aga hat geschrieben:Btw, gibt's in Python so was wie Reflection in Java?
Ja, wenn man das Ruby-Beispiel (oder auch das Java-Beispiel) übersetzt:

Code: Alles auswählen

class Foo(object):
    def hello(self):
        print 'hello'

# sieht recht kompliziert aus, ist aber eigentlich ganz simpel
getattr(globals()['Foo'](), 'hello')()

Verfasst: Samstag 24. März 2007, 10:33
von aga
Danke, das war genau was ich gesucht habe ...

Code: Alles auswählen

def create_instance(*args, **kwargs):
    module, class_ = args[:2]
    cls = getattr(__import__(module, None, None, ['']), class_)
    return cls(*args[2:], **kwargs)

foo = create_instance("my.module", "MyClass", "some", "arguments", keywordargumets="too")
:D :D