Ein paar Fragen über das überladen von operatoren...

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.
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Dienstag 30. Januar 2007, 12:54

So. Ich versuche mich gerade, in meiner verlängerten Pause in die Methodik hereinzulesen, wie blackbird's Tekisuto funktioniert...

Da dort sehr viel via überladene Operatoren erledigt wird wollte ich mir hier bei einigen Sachen nochmal Klarheit verschaffen.

Fangen wir mal an.
''__new__'' und ''__init__'' hab ich schonmal verstanden.

genauso wie ''__str__''. Das klappt :=)

Jedoch... gibt es dort z.B.

''__repr__''. hier verstehe ich nur Bahnhof. Selbst die Dokumentation hilft mir nicht weiter... Was genau macht __repr__() ?

''__lt__( self, other) ''
''__le__( self, other) ''
''__eq__( self, other) ''
''__ne__( self, other) ''
''__gt__( self, other) ''

sagen mir genauso wenig. Mein Buch sowie die Dokumentation geben mir hier auch keine Auskunft.

Ich kann nur raten, das sie indirekt etwas mit ''__cmp__'' zu tun hat.


Habt ihr dort genauere Informationen - Dokumentationen - Artikel?

Würde mich freuen :)

MfG EnTeQuAk
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Dienstag 30. Januar 2007, 13:05

EnTeQuAk hat geschrieben: ''__repr__''. hier verstehe ich nur Bahnhof. Selbst die Dokumentation hilft mir nicht weiter... Was genau macht __repr__() ?
Naja, das zeigt dir genau an was in der Klasse/Instanz ist wenn du ``repr(foo)`` aufrufst.

Code: Alles auswählen

str_ = u"fööbär"
print repr(str_) # u'f\xf6\xf6b\xe4r'
€: Hier zeigt dir repr bei einem Unicode-String an, welche Hexadezimale es in dem gewählt Coding ist.

EnTeQuAk hat geschrieben: ''__lt__( self, other) ''
''__le__( self, other) ''
''__eq__( self, other) ''
''__ne__( self, other) ''
''__gt__( self, other) ''

sagen mir genauso wenig. Mein Buch sowie die Dokumentation geben mir hier auch keine Auskunft.
Dann hast du die falsche. http://docs.python.org/ref/customization.html

x<y = calls x.__lt__(y), x<=y calls x.__le__(y), etc

BTW: __new__ habe ich nicht verstanden. Wie geht das genau?

lg
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Dienstag 30. Januar 2007, 13:18

ACH DAAA ;)

Die Seite hab ich mir schon angeschaut gehabt... nur habe ich den Absatz, unter den Sachen, da nur für das ''__ge__'' gesehen :)

Sorry. Ich dachte, die hätten nicht alle ganz so viel miteinander zu tun.

Hmmm... ''__repr__'' schaut doch schon schick aus. so langsam komme ich hinter die Arbeitsweise einiger Lexer :)


MfG EnTeQuAk
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Dienstag 30. Januar 2007, 14:05

Btw:

ich hab grad lokal hier Python zum laufen bekommen und '__repr__' ausprobieren können.


folgendes ist herausgekommen:

Code: Alles auswählen

class Test(object):
    def __init__(self):
        self.da = 'da'
    def __repr__(self):
        return ''.join(self.__class__.__name__)

# und testen
da = Test()
repr(da)
print da
So... verwirrt vllt :)

Aber wenn man

Code: Alles auswählen

class Test2(object):
    def __init__(self):
        self.da = 'da'
    def __str__(self):
        return self.da
    def __repr__(self):
        return ''.join(self.__class__.__name__)

# und testen
da = Test()
repr(da)
print da
dann kommt alles heraus, wofür __repr__ da ist :D

So... die anderen schau ich mir dann aúch gleich mal an.


MfG EnTeQuAk
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Dienstag 30. Januar 2007, 14:20

Darf man fragen, was der Gedanke hinter

Code: Alles auswählen

    def __repr__(self):
        return ''.join(self.__class__.__name__)
ist, insbesondere hinter dem join(...)?

self.__class__.__name__ wird dir afaik immer einen string wiedergeben (den Namen der Klasse, die dir __class__ zurückgibt).
Natürlich kann man den joinen, weil er als String iterabel ist, aber imho sollte für alle Strings gelten

Code: Alles auswählen

s == ''.join(s)
Zu __repr__ möchte ich anmerken, dass es meines Wissens "deprecated" ist.
Benutzeravatar
jens
Moderator
Beiträge: 8482
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Dienstag 30. Januar 2007, 14:23

EnTeQuAk hat geschrieben:

Code: Alles auswählen

# und testen
da = Test()
repr(da)
print da
Das macht null Sinn ;)

So geht's ehr:

Code: Alles auswählen

# und testen
da = Test()
print repr(da)
:lol:

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Dienstag 30. Januar 2007, 14:26

EDIT:
das mit dem testen da oben war in einer Python-Shell-Sitzung. daher machte das schon ein klein wenig sinn, da mir das dort ausgegeben wurde -- sorry hab ich vergessen zu erwähnen


Wie an den Klassennamen zu merken :D es war nur ein Test. Daher habe ich mir über Sinn und Unsinn mal keine Gedanken gemacht.

Zu __repr__ möchte ich anmerken, dass es meines Wissens "deprecated" ist.
hmm... warum?
Natürlich kann man den joinen, weil er als String iterabel ist, aber imho sollte für alle Strings gelten

Code: Alles auswählen

s == ''.join(s)
bin ich auf dem falschen Dampfer oder macht das nur für mich keinen Sinn, da da so oder so 'True' rauskommt?

Oder was war bei dir der Hintergedanke? :D

MfG EnTeQuAk
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Dienstag 30. Januar 2007, 15:01

[warum ist repr deprecated]
Nagele mich nicht drauf fest, ich erinnere mich, da was gelesen zu haben, was darauf rauslief, dass es kaum einer richtig benutzt (soll heissen: repr gibt etwas aus, was nicht nur hübsch aussieht, sondern auch ein legales python-statement ist), und man es deshalb eigentlich eh nicht benutzen kann. Kann ich eigentlich ganz gut nachvollziehen, und es hindert ja niemanden daran, für sich ein "representable"-Protokoll zu erfinden.
bin ich auf dem falschen Dampfer oder macht das nur für mich keinen Sinn, da da so oder so 'True' rauskommt?
Doch, doch, du hast recht, es kommt immer True raus: das ganze ist eine Tautologie, deshalb sagte ich ja "es gilt für alle strings". Eigentlich wollte ich damit zeigen, dass dein Statement nicht falsch (im Sinne der Funktionalität), sondern nur unnötig kompliziert ist, weil ich annahm, dass sei Absicht.
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Dienstag 30. Januar 2007, 15:23

ACHSOOOOO :D


Dann haben wir uns ja im Enddefekt verstanden :D


Und ich bin wieder einen Schritt weiter in Python gekommen... Ich mag es :D


MfG EnTeQuAk
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Dienstag 30. Januar 2007, 17:55

keppla hat geschrieben: Zu __repr__ möchte ich anmerken, dass es meines Wissens "deprecated" ist.
Ist es nicht.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
BlackJack

Dienstag 30. Januar 2007, 20:10

keppla hat geschrieben:[warum ist repr deprecated]
Nagele mich nicht drauf fest, ich erinnere mich, da was gelesen zu haben, was darauf rauslief, dass es kaum einer richtig benutzt (soll heissen: repr gibt etwas aus, was nicht nur hübsch aussieht, sondern auch ein legales python-statement ist), und man es deshalb eigentlich eh nicht benutzen kann. Kann ich eigentlich ganz gut nachvollziehen, und es hindert ja niemanden daran, für sich ein "representable"-Protokoll zu erfinden.
`repr` muss nicht "legales Python" zurückgeben. Wenn das einfach möglich ist, wäre es schön, aber es muss nicht. Falls es nicht möglich ist, wird empfohlen etwas aussagekräftiges zurückzugeben, das in '<…>' eingeschlossen ist. Und das habe ich bisher auch so ziemlich überall so implementiert gesehen.

Ich wüsste auch nicht wie man ein Python-Programm debuggen sollte, ohne mit `repr()` nachschauen zu können, an was bestimmte Namen wirklich gebunden sind.
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Mittwoch 31. Januar 2007, 16:29

`repr` muss nicht "legales Python" zurückgeben
ok, ich sollte mich etwas näher an das RFC, was "muss", "soll", "kann" definiert halten. ;)

Ich hab nochmal etwas gesucht, und da, wo ich dachte, ich hätte es gelesen, nichts solches gefunden, und muss mich dementsprechend für das verbreiten von falschinformationen entschuldigen: ich hatte da was falsch in Erinnerung, birkenfeld hat recht.

Code: Alles auswählen

Ich wüsste auch nicht wie man ein Python-Programm debuggen sollte, ohne mit `repr()` nachschauen zu können, an was bestimmte Namen wirklich gebunden sind.
dazu braucht man nicht unbedingt die Unterscheidung str und repr, z.B. Java kommt auch mit nur .toString aus. id() ist ausserdem eindeutiger ;)
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Mittwoch 31. Januar 2007, 16:45

keppla hat geschrieben: dazu braucht man nicht unbedingt die Unterscheidung str und repr, z.B. Java kommt auch mit nur .toString aus.
Dann unterscheide doch mal anhand von str() "1" und 1.
Oder "1.0" und 1.0. Oder...

Um da den Durchblick zu behalten, musst du zumindest den Typ noch mit dazu ausgeben. Genau das macht aber repr().
id() ist ausserdem eindeutiger ;)
id() bringt dir garnix.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Mittwoch 31. Januar 2007, 16:53

keppla hat geschrieben: dazu braucht man nicht unbedingt die Unterscheidung str und repr, z.B. Java kommt auch mit nur .toString aus. id() ist ausserdem eindeutiger ;)
In wiefern eindeutiger? Mit einer Zahl kann ich persönlich ohne andere Informationen wenig anfangen. Und das was repr ausgibt oder ausgeben sollte ist ja ein wenig mehr als nur eine Zahl (Oder "Adresse" im Default mode).

Ich finde es z.B. nicht schlecht das ich mit __str__ mir nur das anzeigen lassen kann was wichtig ist nach ausenhin, aber mit __repr__ (zusätzlich) ein wenig mehr Daten über Interna :) Das hilf schon beim Debuggen, wenn man weiß womit man es zu tun hat. Ich überlade __repr__ auch so ähnlich wie im Tekisuto-Code von BlackBird.

Also kurz: Für mich gehört es einfach dazu, dass wenn ich repr(foo) nutze, mir der Name der Klasse zurückgegeben wird, damit ich weiß an was der Name `foo` gebunden ist (Ist im Default ja schon so + "Addresse", etc).
Oft genügen mir diese Information nicht und will ein par Infos (Ohne nötigen Schreibkram) über das interne mehr haben und überlade __repr__ da entsprechend. Wichtig ist aber, dass in der Überladung IMHO immer zusätlich sowas ``self.__class__.__name__`` zurückgegeben werden muss, damit man auch sieht an was ``foo`` gebunden ist.

BTW: Daher finde ich id() auch unpassend, da ich mit einer ID immer eine eindeutige (Kollisionsfreie) Zahl, assoziiere.

lg
EDIT:
BTW: Außerdem ist id() schon von Python als Keyword belegt ;) Es sein den du meintest das du die Benutzung von id() eindeutiger findest :shock:
Antworten