dynamische Instanzierung?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
aga
User
Beiträge: 18
Registriert: Montag 12. März 2007, 15:36

Freitag 23. März 2007, 12:44

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
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Freitag 23. März 2007, 13:01

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
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Freitag 23. März 2007, 13:52

Mit den locals() fällt man nur innerhalb von Funktionen auf die Schnauze.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Freitag 23. März 2007, 14:03

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
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Freitag 23. März 2007, 14:06

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")
TUFKAB – the user formerly known as blackbird
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Freitag 23. März 2007, 14:50

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
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Freitag 23. März 2007, 15:32

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.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Freitag 23. März 2007, 17:14

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')()
My god, it's full of CARs! | Leonidasvoice vs Modvoice
aga
User
Beiträge: 18
Registriert: Montag 12. März 2007, 15:36

Samstag 24. März 2007, 10:33

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
Antworten