Vererbung von Instanzen

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
schneitzmaster
User
Beiträge: 94
Registriert: Freitag 26. Oktober 2012, 15:35
Wohnort: Hamburg

Hallo Leute,

ich möchte Vererbung benutzen um die Attribute einer Instanz weiterzugeben.
Das folgende Minimalbeispiel klappt leider nicht:

Code: Alles auswählen

class Shape(object):
    def __init__(self):
        self.color   = 'color'

class triangle(Shape):
    def __init_(self):
        self.corners = 3

abstract_shape       = Shape()
abstract_shape.color = 'red'
# Give shape a color
print abstract_shape.color
# Make shape a triangle
red_tri = triangle(abstract_shape)
print red_tri.color
Hat jemand eine Idee, wie das Ganz umzusetzen ist?
BlackJack

@schneitzmaster: Ich bin mir nicht sicher was ich darauf antworten soll. Was Du da anscheinend versuchst ist so nicht vorgesehen. Man würde gleich ein `triangle`-Objekt erstellen und nicht nachträglich aus einem `Shape` versuchen ein `triangle` zu machen. Und dann hat man alle Attribute wenn man in der Unterklasse in der `__init__()` die `__init__()` der Basisklasse aufruft. Das fehlt in Deinem Beispiel.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@schneitzmaster
Irgendwo muss ja eine Verbindung zwischen `Triangle` und `Shape` entstehen, was in Deinem Beispiel nicht der Fall ist. So sollte es aussehen:

Code: Alles auswählen

>>> class Shape(object):
...     def __init__(self):
...         self.color = 'color'
...
>>> class Triangle(Shape):
...     def __init__(self):
...         Shape.__init__(self)
...         self.corners = 3
... 
>>> shape = Shape()
>>> triangle = Triangle()
>>> shape.color = 'red'
>>> triangle.color
'color'
Interessant dazu: Inheritance

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
schneitzmaster
User
Beiträge: 94
Registriert: Freitag 26. Oktober 2012, 15:35
Wohnort: Hamburg

danke für die antworten

@BlackJack: Ich hab mir schon gedacht, dass es nicht vorgesehen ist. Vielleicht ist mein Ansatz ja der Falsche, um das Problem zu lösen. Was ich machen möchte, an dem gewählten Beispiel erklärt:
Ich habe eine Shape-"Oberklasse". Dieser weise ich Attribute zu. Im Verlauf des Programmes iniziere ich eine Shape-Instanz (abstract_shape). Dann werden diverse Operationen ausgeführt, die unteranderem dazu führen, dass abstract_shape eine Farbe zu gewiesen wird (red). Dann wird weiterentschieden ob aus der Form noch ein Dreieck wird oder vielleicht auch ein Kreis usw. Dabei möchte ich die in abstract_shape schon gespeicherten Attribute auf die nächste Instanz (triangle) vererben. Alles noch mal ausrechnen mit den Methoden von Shape wäre zusätzlicher Rechenaufwand. Da erst im Verlauf des Programmes das Attribut zugewiesen wird, kann ich das nicht schon bei der Definition der Klasse machen. Geht das irgendwie elegant über Vererbung oder ist Vererbung nur als etwas abstractes in der Definition von Objekten zu betrachten.

@mutetella: die verbindung zwischne Triangle und Shape ist ja durch Triangle(Shape) gegeben (dachte ich zu mindest).
BlackJack

@schneitzmaster: Das was Du machen willst hat nichts mit Vererbung zu tun. Das sieht eher wie das „builder pattern” aus. Oder vielleicht auch etwas ganz anderes, je nachdem welches Problem da *tatsächlich* gelöst werden soll.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@schneitzmaster
Dann übergib' Deinem `Triangle` Exemplar doch ein `Shape` Exemplar:

Code: Alles auswählen

>>> class Shape(object):
...     def __init__(self):
...         self.color = 'color'
... 
>>> class Triangle(object):
...     def __init__(self, shape):
...         self.shape = shape
...         self.corners = 3
... 
>>> shape = Shape()
>>> triangle = Triangle(shape)
>>> triangle.shape.color
'color'
>>> shape.color = 'red'
>>> triangle.shape.color
'red'
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
schneitzmaster
User
Beiträge: 94
Registriert: Freitag 26. Oktober 2012, 15:35
Wohnort: Hamburg

@mutetella: Ja das sieht gut aus. Werden so auch Methoden mit übergeben?
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@schneitzmaster
Ein Exemplar (Instanz) ist eine zum Leben erweckte Klasse. Alles, was der (Klassen-)Bauplan beinhaltet, ist selbstverständlich beim Exemplar vorhanden und im Falle der Methoden auch erst dort verwendbar:

Code: Alles auswählen

>>> class Dog(object):
...     def __init__(self, age):
...         self.age = age
...     def bark(self):
...         if self.age == 'puppy'
...             print 'wow-wow-wow-wow'
...         else:
...             print 'WUFF'
... 
>>> Dog.bark()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method bark() must be called with Dog instance as first argument (got nothing instead)
>>> dog = Dog('puppy')
>>> dog.bark()
wow-wow-wow-wow
Das ... (got nothing instead) ... in der Fehlermeldung sagt eigentlich alles aus!

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Imho musst Du Dir erst einmal klar werden, *inwiefern* Deine Entitäten zueinander in Beziehung stehen. Sind das "Ist ein" oder "hat ein"-Beziehungen. Das ist i.A. ein brauchbarer Weg, um abzuschätzen, welche Entitäten durch Vererbung miteinander verbunden sind und welche besser durch Komposition verbunden werden sollten.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Da das Wort nicht einmal gefallen ist, das nennt sich Copy-Konstruktor.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@darktrym: Ist vielleicht nicht gefallen weil das hier Python und nicht C++ ist. :-) In Python ist das im Gegensatz zu C++ kein geläufiger Begriff.
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Wusste gar nicht dass das sprachspezisch ist, so heißt das Teil in der OOP-Welt.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@darktrym: Der Artikel hat als einzige Literaturquelle „Die C++ Programmiersprache“ von Stroustrup. Und bei C++ braucht man den Copy-Konstruktor beziehungsweise muss zumindest wissen was das ist weil der für so etwas grundlegendes wie einfache Zuweisungen und Parameterübergaben wichtig sein kann. In Java hat `Object` eine `clone()`-Methode, weshalb man dort auch selten bis gar keine Copy-Konstruktoren sieht, und wenn, dann oft von C++-Programmierern die Java lernen (oder C++ in Java-Syntax schreiben wollen ;-)). Die englischsprachige Wikipedia hat ein eigenes Lemma für „Copy constructor (C++)“ — eben weil das in C++ etwas besonderes/wichtiges ist.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

darktrym hat geschrieben:Da das Wort nicht einmal gefallen ist, das nennt sich Copy-Konstruktor.
Auch wenn schon geklärt worden ist, dass das kein pythonischer Begriff ist: Was meinst Du denn mit *das*? Also welche Sache in welchem Teil des Threads hier würdest Du so nennen?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Zeile 14 erster Beitrag?
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@darktrym: Ist das tatsächlich einer? Da wird ja kein Wert vom gleichen Typ übergeben.
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Stimmt, aber die Absicht war erkennbar. Man wollte die Belegung der Instanz mit der Erzeugung einer neuen abgleichen. Das funktioniert zmd. so nicht unter C++.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Antworten