type()-funktionalität bei eigenen Objekten

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
...
User
Beiträge: 116
Registriert: Mittwoch 23. Dezember 2009, 20:22

Hey,


Ich soll im Studium eine Klasse Car entwerfen

Code: Alles auswählen

class Car:
    def __init__(self, manufacturer, model, color):
        self.manufacturer = manufacturer
        self.model = model
        self.color = color

    def ... einige weitere Funktionen wie repaint usw...

    def __eq__:
        !!!
 
Ja, hier bei der def __eq__ hab ich mein Problem.
In der Aufgabe wurde ausdrücklich, darauf hingewiesen, das es mit etwas beliebigem verglichen werden können soll, z.B. 3
type() würde weiterhelfen. Gut, Danke ;-)

Meine momentane, nicht ganz ausgereifte Methode kommt allerdings ohne type aus, und schaut so aus:

Code: Alles auswählen

def __eq__(self, other):
    try:
        return self.manufacturer == other.manufacturer \
           and self.model == other.model \
           and self.color == other.color
    except AttributeError:
        return False
Blöd ist: Es ist nicht abgedeckt, ob es sich dabei tatsächlich um eine Instanz von Car handelt.
Darum möchte ich doch gerne hinzufügen
type(self) == type(other)
Da theoretisch eine Klasse "Motorräder", für Fantasienamen die selben Einträge hat, wenn sie genau so gestaltet ist.
Damit type(self) == type(other) funktionier muss ja aber irgendwie type() dazu gebracht werden,
etwas anderes auszuspucken als nur <type "Instance">

Wie bekomme ich das hin?


lg,
...
ichisich
User
Beiträge: 134
Registriert: Freitag 1. Januar 2010, 11:52

mir ist spontan

Code: Alles auswählen

isinstance
in den Kopf gekommen und dann dieser Link untergekommen.

Gruß
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

... hat geschrieben:Blöd ist: Es ist nicht abgedeckt, ob es sich dabei tatsächlich um eine Instanz von Car handelt.
Warum willst du das überhaupt prüfen?
type(self) == type(other)
Da theoretisch eine Klasse "Motorräder", für Fantasienamen die selben Einträge hat, wenn sie genau so gestaltet ist.
Damit type(self) == type(other) funktionier muss ja aber irgendwie type() dazu gebracht werden,
etwas anderes auszuspucken als nur <type "Instance">

Wie bekomme ich das hin?
[/quote]Klasse von object erben lassen, was du übrigens generell immer tun solltest.

Aber wie ichisich schon angedeutet hat, wenn du schon eine Typprüfung machen willst, dann bitte mit isinstance isinstance(other, Car). Besser wäre es vermutlich der Klasse ein Attribut namens „vehicle_type“ zu verpassen und dort Motorrad oder Auto reinzuschreiben. Typprüfungen riechen meist ein bisschen streng.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hmm, also ich find den Code der nur Duck-Typing nutzt eigentlich schon ganz ok. Wenn Motorräder sich mit Autos vergleichen lassen sollen, dann passts doch. Wenn es wie ein Auto einen Hersteller hat, eine Modellnummer hat und eine Farbe, dann ist es wohl ein Auto, frei nach dem Duck-Typing-Motto.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich hatte mir vorhin mal Gedanken zur Vererbungsproblematik bei der Verwendung von isinstance gemacht. Schließlich soll man ja wohl Subklassen mit Elternklassen vergleichen können, aber nicht umgekehrt.

Und siehe da, Python denkt da genauso :-)

Code: Alles auswählen

In [1]: class A(object):
   ...:     pass
   ...: 

In [3]: class B(A):
   ...:     pass
   ...: 

In [4]: a = A()

In [5]: b = B()

In [6]: isinstance(a, A)
Out[6]: True

In [7]: isinstance(b, A)
Out[7]: True

In [8]: isinstance(b, B)
Out[8]: True

In [9]: isinstance(a, B)
Out[9]: False
Ok, hätte man auch nachlesen können:
Doku hat geschrieben: Return true if the object argument is an instance of the classinfo argument, or of a (direct or indirect) subclass thereof. Also return true if classinfo is a type object (new-style class) and object is an object of that type or of a (direct or indirect) subclass thereof.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ganz abgesehn davon, dass es Vererbung als solches ad absurdum fuehren wuerde ;) Aber wenn ich den OP richtig verstehe ist ja ein besonders restriktives Vorgehen gewuenscht, insofern ist das nur gut.

Oh und fuer den Fall dass es noch nich genug Stimmen fuer Duck-Typing gab: Me too!

When in Python quack like a duck. Oder `duck like a duck`? Hum.
...
User
Beiträge: 116
Registriert: Mittwoch 23. Dezember 2009, 20:22

;-) Wie gesagt, ist für's Studium.

Wir müssen uns immer strikt an die Aufgabe halten. Und wenn da steht, wir sollen eine Typen-Prüfung durchführen,
dann muss ich leider das Duck-Typing lassen, denke ich.
Ich hatte bereits darüber nachgedacht, ob ich einfach per Kommentar auf Duck-Typing verweisen sollte.
Ich wäre früher nie auf die Idee gekommen, eine Typenprüfung dieser Art einzufügen,
sondern eben einfach die Attribute in nem try-block mit except AttributeError überprüft.
Zudem ja das Erben, welches wir aber vermutlich nicht anwenden sollen, da wir Python als Funktionale und nur so wenig wie möglich als Object-Orientierte Sprache lernen sollen, so unser Prof.
Fragt besser nicht, ich möchte hier nicht über das für und wieder von Unsinn Diskutieren.

Vielen Dank für den Hinweis mit isinstance(). Das hat mir weiter geholfen.


Was mich jetzt aber dennoch Interessieren würde:
In wieweit kann ich Einfluss auf das Ergebnis einer Typenprüfung mit type() nehmen?

Ginge es, das hier:

Code: Alles auswählen

class Car(object):
    def __init__(self):
        pass

print(type(Car()))
nicht <class '__main__.Car'>
sondern z.B. <hallo 'welt'> rauskommt... oder irgend was anderes?

Das ist jetzt nur noch der reinen Neugierde halber.


lg,
Michael
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

... hat geschrieben:In wieweit kann ich Einfluss auf das Ergebnis einer Typenprüfung mit type() nehmen?
Du könntest die Funktion type überschreiben.
nicht <class '__main__.Car'>
sondern z.B. <hallo 'welt'> rauskommt... oder irgend was anderes?
Das ist nicht das Ergebnis der Typprüfung (type() prüft nichts), sondern die Zeichenketten-Repräsentation des typs (in diesem Fall die Klasse Car).

Dementsprechend kannst du diese durch überschreiben der __repr__-Methode der Metaklasse von Car verändern.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

... hat geschrieben:;-) Wie gesagt, ist für's Studium.
Als Student sollte man imho genug Selbstbewusstsein mitbringen, um nicht jeden Unsinn mitzumachen. Andererseits braucht es genug Demut, um nicht in Konflikt mit formal höher gestellten Menschen zu kommen. Insofern würde ich die Duck-Typing Lösung in Kommentaren hinschreiben und die geforderte Lösung implementieren oder umgekehrt. Zumindest wenn's nicht sehr viel mehr Arbeit macht.

Schaut sich denn wirklich der Prof persönlich die Aufgaben an? Oder sind es Assistenten oder Hiwis? Je nach Typ Mensch kann man durchaus mit solchen Leuten diskutieren und seinen Standpunkt deutlich machen, sollte es zu Konflikten kommen. Wichtig wären da entsprechende "Belege", auf die man sich berufen kann. Aber das Python-Zen sollte da ja schon ausreichen :-) (Richtig hübsch wäre wohl auch ein Code-Schnipsel aus der Standard-Lib)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
lunar

@Hyperion: Es ist bestimmt nicht Ziel der betreffenden Vorlesung, idiomatisches Python zu lehren, sondern den Studenten anhand von Python irgendwelche allgemeineren Konzepte beizubringen. Python ist nur Mittel zum Zweck, das Studium ist ja auch kein Programmierkurs. Insofern gibt es gerade als Student doch tausend sinnvollere Dinge als kleinkarierte Diskussionen über Idiome zu beginnen, zumal man sich damit bei der Übungsleitung auch nicht sonderlich beliebt macht. ;)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Also ich war als Übungsleiter alternativen Lösungen gegenüber immer aufgeschlossen, sofern sie gut begründet wurden. Ich schrieb dazu ja auch sinngemäß "wenn es keine Mühe macht". Muss halt jeder selber für sich überlegen und auch natürlich den Kontext beachten.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ja, stimme Hyperion zu. Und wie oft ich mich mit der Übungsleitung angelegt hab, kann man teilweise an der Anzahl Übungsblätter einiger Vorlesungen direkt abzählen :?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
lunar

@Hyperion: Gegen "alternative Lösungen" ist, sofern sie die Aufgabenstellung richtig lösen, ja nichts einzuwenden. Die Diskussionen über Sinn und Unsinn einer Aufgabenstellung oder gleich des Lehrinhalts allgemein aber nerven gewaltig, vor allem in verpflichtenden Grundlagenfächern, die wenig mit dem zu tun haben, was Studenten für "die Praxis" halten.

Außerdem: Ausnahmen bestätigen jede Regel ;) Es gibt solche und solche Übungsleiter, je nachdem auch, ob die betreffende Person den Job gerne macht, oder dazu verdonnert wurde. Nicht jeder ist zur Lehre geboren.

@Leonidas: In der Tat? Ich glaube, ich habe noch keine einzige Diskussion mit der Übungsleitung geführt. Die mitunter tatsächlich abstrusen Aufgaben aus manchen Grundlagenfächern (GRV ;) ) habe ich einfach gelöst oder abgeschrieben, abgegeben, vergessen und mich anderen, für mich sinnvolleren Dingen zugewandt.

Auch glaube ich, dass Deine Kritik etwas kompetenter und konstruktiver ist als "Info2 Blödsinn, weil kein Java, und kein Praxisbezug", und insofern wärst Du dann auch eine Ausnahme ;)
Antworten