geerbte classmethod überschreiben

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
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

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()
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
rads
User
Beiträge: 153
Registriert: Freitag 26. März 2010, 15:51

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
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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
Das Leben ist wie ein Tennisball.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

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.
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

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).
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

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?
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

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.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

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.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

/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'
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Danke euch! :)
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Antworten