Doku: von Klassen ableiten...

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
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Es scheint ja ganz nützlich zu sein, von anderen Klassen abzuleiten... Aber wo finde ich eigentlich Dokus zu dem Thema?

z.B. das Ableiten von list():

Code: Alles auswählen

class files(list):
    def append(self, value):
        print "append:",value
        list.append(self, value)

f = files()
f.append("TEST")
print f
Mittels print help(f.append) konnte ich rausfinden, wie append() aufgebaut ist...
Nun möchte ich aber auch print f manipulieren, das z.B. auch erweitern mit einer print-Ausgabe...
Aber da weiß ich nicht, welche Funktion benutzt wird... Natürlich habe ich mit for i in dir(f): print i eine Liste aller Methoden, aber welche ist die richtige?
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi jens,

für die Ausgabe mit print, wird die Methode __str__(self) von Objekten benutzt. Wenn keine Methode __str__ vorhanden ist wird __repr__ verwendet, ist auch das nicht definiert wird eine Standartfunktion zur Darstellung von Objekten verwendet. Siehe auch http://docs.python.org/ref/customization.html

Dann ist noch http://www.python.org/doc/2.2.3/whatsne ... links.html interessant. Hier werden verschiedene Aspekte von Newstyle-Klassen beleuchtet. Alle Builtintypen sind seit Python2.2 Newstyle-Klassen.

Kleine Ergänzung deines Beispiels:

Code: Alles auswählen

class files(list):
    def append(self, value):
        print "append:",value
        super(files, self).append(value) # append über super aufrufen

    def __str__(self, value):
        indent = " " * len(self.__class__.__name__)
        content = indent.join([str(x)+'\n' for x in self])[:-1]
        txt = "%s([%s])" % (self.__class__.__name__, content)
        return txt 
f = files()
f.append("TEST")
print f

Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

append über super aufzurufen, hat allerdings einen großen Nachteil, weil der Name der Klasse drin steht.... Somit ist ein umbenennen der Klasse nicht ohne weiteres möglich :(

Hier hab ich schon mal vorgearbeitet:
http://de.wikibooks.org/wiki/Python-Pro ... on_Klassen
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

append über super aufzurufen, hat allerdings zwei entscheidende Vorteile, wenn du eine andere Basisklasse verwenden willst, brauchst du an den Methoden nichts ändern und wenn du Mehrfachvererbung einbaust geht's kaum ohne super. ;)


Dookie
[code]#!/usr/bin/env python
import this[/code]
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hmmm... Deswegen hab ich ja auch bei wikibooks direkt auch ein paar Überschriften für super gemacht ;)

Wäre super, wenn du da die Beispiele in "super-Klassen" übersetzten könntest...

Gibt es denn nicht eine Möglichkeit, das der KlassenName beim Aufruf [bsp.: super(files, self).append(value)] verallgemeinert wird? So das es halt immer gültig ist, egal wie die Klasse heißt?
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hab jetzt mal das dict vervollständigt... Ich denke das sind die wichtigsten Methoden:

Code: Alles auswählen

class bsp(dict):
    def keys(self):
        print "keys:",
        return dict.keys(self)

    def __setitem__(self, item, value):
        print "__setitem__[%s]=%s" % (item,value)
        dict.__setitem__(self, item, value)

    def __getitem__(self, key):
        print "__getitem__[%s]:" % key,
        dict.__getitem__(self, key)

    def __str__(self):
        print "__str__:",
        return dict.__str__(self)

    def __len__(self):
        print "__len__:",
        return dict.__len__(self)

    def __delitem__(self, key):
        print "__delitem__[%s]" % key
        dict.__delitem__(self, key)

    def has_key(self, key):
        print "has_key(%s):" % key,
        return dict.has_key(self, key)

    def iteritems(self):
        print "iteritems:"
        return dict.iteritems(self)

    def values(self):
        print "values:",
        return dict.values(self)

d = bsp()
print "01",; d[1]="eins"
print "02",; d["zwei"] = 2
print "03",; print d
print "04",; print d[1]
print "05",; print d.keys()
print "06",; print len(d)
print "07",; del(d["zwei"])
print "08",; print d.has_key("zwei")
print "09",; d[2]="zwei"
print
print "10",
for key, item in d.iteritems():
    print "10", key, item
print
print "11",; print d.values()
Ausgaben:
01 __setitem__[1]=eins
02 __setitem__[zwei]=2
03 __str__:{1: 'eins', 'zwei': 2}
04 __getitem__[1]: None
05 keys: [1, 'zwei']
06 __len__: 2
07 __delitem__[zwei]
08 has_key(zwei): False
09 __setitem__[2]=zwei

10 iteritems:
10 1 eins
10 2 zwei

11 values: ['eins', 'zwei']
Noch eine Frage... Wann wird __repr__ benutzt?

EDIT: Wie es besser geht, steht hier: http://www.python-forum.de/viewtopic.php?t=4918
Antworten