Seite 1 von 1

geerbte classmethod überschreiben

Verfasst: Freitag 16. Juli 2010, 13:46
von jbs
Hi

ich stehe vor folgendem Problem: Ich habe eine Klasse D, die von C erbt. C besitzt eine `classmethod`, die D überschreibt. Ich möchte nun aber in der überschreibenden Methode die Klassenmethode von C aufrufen.

Ist das möglich?


Edit:

Hier mal wie ich mir das vorstelle:


Code: Alles auswählen

class A(object):
    
    def __init__(self):
        print self
    
    @classmethod
    def method(cls):
        #cls soll dann B sein
        print cls
    
    

class B(A):
    
    def __init__(self):
        A.__init__(self)

    @classmethod
    def method(cls):
        A.method()


B()
B.method()

Re: geerbte classmethod überschreiben

Verfasst: Freitag 16. Juli 2010, 13:58
von rads
Hat man eine Methode der Elternklasse überschrieben und möchte trotzdem auf die Methode der Elternklasse zugreifen steht dafür die Funktion super zur Verfügung, die das Dictionaries der Elternklassen mach der Methode sucht. Die Funktion super steht nur für New-Style-Klassen zur Verfügnung.

Code: Alles auswählen

class B(A):
    def say(self, text1, text2):
        return 'My Papa says: '+super(B, self).say(text1) +'\n' \
              +'and I say: '+text2
 
>>> b=B()
>>> b.say('Hallo', 'Hi')
My Papa says: Im class A and say: Hallo
and I say: Hi
[Quelle: http://de.wikibooks.org/wiki/Python-Pro ... nd_Klassen]

Aber ich werde bestimmt korrigiert werden wenn das zu nah an c# und java ist.

Grüße

Re: geerbte classmethod überschreiben

Verfasst: Freitag 16. Juli 2010, 14:29
von EyDu
Hallo.

Ich habe den classmethod-Deskriptor jetzt nicht genau im Kopf, ich lehne mich aber mal ein wenig aus dem Fenster und behaupte, dass das auf diesem Weg nichts wird. Ich würde einen Umweg über statische Methoden gehen oder vorher noch nach ein wenig Metamagie suchen. Oder du verrätst dein eigentliches Vorhaben, vielleicht gibt es einen besseren Weg.

Sebastian

Re: geerbte classmethod überschreiben

Verfasst: Freitag 16. Juli 2010, 15:25
von jbs
Ich glaube ich stelle das Design um ;). Das ist klarer und nicht so magisch.

Ich habe vor Kartenspiele zu programmieren und erstelle mit einer Klassenmethode ein Deck aus den Spielkarten.

Beispielsweise werden im Skat die Karten 7-Ass verwendet, im Doppelkopf alle Karten von 10-Ass doppelt. Ich wollte eigene Klassen für jedes Spiel erstellen, die dann mittels Klassenatributen die Karten einschränken. Die Basisklasse enthält eine Methode, die alle möglichen Karten erstellt. Für Doppelkopf, wollte ich die Methode überschreiben und einfach das Ergebnis der Superklasse verdoppeln. Die Superklasse sollte auf die Regeln der Doppelkopfkartenklasse zugreifen können.

Wenn ich mir das so überlege, dann ist es besser für jedes Spiel einen Kontext anzulegen, der dann die Karten erstellt und weitere Regeln beachtet.

Re: geerbte classmethod überschreiben

Verfasst: Freitag 16. Juli 2010, 16:41
von Darii
EyDu hat geschrieben:Ich habe den classmethod-Deskriptor jetzt nicht genau im Kopf, ich lehne mich aber mal ein wenig aus dem Fenster und behaupte, dass das auf diesem Weg nichts wird. Ich würde einen Umweg über statische Methoden gehen oder vorher noch nach ein wenig Metamagie suchen.
Immer gut festhalten beim aus dem Fenster lehnen. :) super funktioniert nämlich auch in Klassenmethoden. Wenn das nicht gehen würde, wären entweder super oder classmethod kaputt.

Der Unterschied zwischen statischen Methoden und Klassenmethoden ist ja gerade, dass bei Klassenmethoden Vererbung und somit insbesondere das Aufrufen von Methoden der Superklasse möglich ist. Bei Python ist das Besondere ist eben nur, dass die Klassenmethoden meist in der Klasse selbst und nicht in ihrer Metaklasse zu finden sind, was durch die Deskriptoren ermöglicht wird (die aber auch nur halb durchdacht sind, ein @classproperty lässt sich ohne Metaklassen z.B. nicht implementieren).

Re: geerbte classmethod überschreiben

Verfasst: Freitag 16. Juli 2010, 17:25
von jbs
Darii hat geschrieben:Der Unterschied zwischen statischen Methoden und Klassenmethoden ist ja gerade, dass bei Klassenmethoden Vererbung und somit insbesondere das Aufrufen von Methoden der Superklasse möglich ist
Wie mache ich das denn?

Re: geerbte classmethod überschreiben

Verfasst: Freitag 16. Juli 2010, 17:30
von DasIch
Darii hat geschrieben:super funktioniert nämlich auch in Klassenmethoden. Wenn das nicht gehen würde, wären entweder super oder classmethod kaputt.
Mal abgesehen davon dass imho super() sowieso schon kaputt ist, wie soll dass hier bitte gehen?

Code: Alles auswählen

>>> class Foo(object):
...     @classmethod
...     def spam(cls):
...         return cls.__name__
... 
>>> class Bar(object):
...     @classmethod
...     def spam(cls):
...         return super(Bar, cls).spam()
... 
>>> Bar().spam()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 4, in spam
AttributeError: 'super' object has no attribute 'spam'
Wahrscheinlich übersehe ich auch nur die offensichtliche Lösung, ich benutze super() sonst nicht.

Re: geerbte classmethod überschreiben

Verfasst: Freitag 16. Juli 2010, 18:09
von /me
DasIch hat geschrieben:Mal abgesehen davon dass imho super() sowieso schon kaputt ist, wie soll dass hier bitte gehen?
Du musst schon Bar von Foo erben lassen, statt von object.

Re: geerbte classmethod überschreiben

Verfasst: Freitag 16. Juli 2010, 18:11
von DasIch
/me hat geschrieben:Du musst schon Bar von Foo erben lassen, statt von object.
Oops. Dann funktioniert es durchaus:

Code: Alles auswählen

>>> class Foo(object):
...     @classmethod
...     def spam(cls):
...         return cls.__name__
... 
>>> class Bar(Foo):
...     @classmethod
...     def spam(cls):
...         return super(Bar, cls).spam()
... 
>>> Bar().spam()
'Bar'

Re: geerbte classmethod überschreiben

Verfasst: Freitag 16. Juli 2010, 18:24
von jbs
Danke euch! :)