AW: [Python-de] dynamisch Methoden aufrufen
Ulrich Berning
ulrich.berning at t-online.de
Mit Nov 12 23:37:46 CET 2003
Rainer Fischbach wrote:
>Kann auch nicht gehen, da die Methoden nicht im __dict__ der Ausprägungen stehen, sondern in dem der Klasse. Dabei musst Du darauf achten, dass dort die ungebundene Methode steht, Du also die Ausprägung explizit als Parameter übergeben musst! So geht's:
>
>C.__dict__[name](c)
>
>
Damit fällt die Vererbung dann unter den Tisch, da die Methoden der
Superklassen nicht im __dict__ einer Klasse auftauchen. Dies gilt auch für:
getattr(c, name)(c)
Folgendes wird funktionieren:
getattr(C, name)(c)
besser wäre:
getattr(c.__class__, name)(c)
da dann nur die Instanz benötigt wird und nicht die Klasse selber. Dann
wird's aber so langsam unleserlich.
Die sauberste Lösung ist, der (Basis-)Klasse eine Methode call_by_name
zu verpassen, die den Aufruf der gewünschten Methode übernimmt und
gegebenenfalls AttributeError wirft:
Beispiel:
-------------------------------------
class A:
def one(self, *args):
print "one called from a %s instance with:" %
self.__class__.__name__, args
def call_by_name(self, name, *args):
getattr(self, name)(*args) # Innerhalb der Klasse geht's mit self
class B(A):
def two(self, a, b, c):
print "two called from a %s instance with:" %
self.__class__.__name__, a, b, c
class C(B):
def three(self):
print "three called from a %s instance" % self.__class__.__name__
a = A()
b = B()
c = C()
a.call_by_name("one", "Hello", "World")
b.call_by_name("one")
b.call_by_name("two", 1, 2, 3)
c.call_by_name("one", [], None, {})
c.call_by_name("two", 4, 5, 6)
c.call_by_name("three")
try:
c.call_by_name("four")
except AttributeError, args:
print "Expected AtributeError:", args
-------------------------------------
Ergebnis:
-------------------------------------
one called from a A instance with: ('Hello', 'World')
one called from a B instance with: ()
two called from a B instance with: 1 2 3
one called from a C instance with: ([], None, {})
two called from a C instance with: 4 5 6
three called from a C instance
Expected AtributeError: C instance has no attribute 'four'
-------------------------------------
Ciao, Ulli