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.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Mittwoch 31. Januar 2007, 17:13

sape hat geschrieben: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:

Klar meint er das. Aber id() ist kein Keyword, sondern eine Funktion in den Builtins.
Dann lieber noch Vim 7 als Windows 7.

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

Beitragvon sape » Mittwoch 31. Januar 2007, 17:16

Ups, stimmt ja.

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

Beitragvon keppla » Samstag 3. Februar 2007, 14:50

id() bringt dir garnix

Wenn ich wissen will, an _welches_ Objekt ein name gebunden ist, bringt mir das mehr als eine (möglicherweise gleich aussehende) Ausgabe eines __repr__. Das meinte ich auch mit eindeutiger:

Code: Alles auswählen

d1 = datetime(2007,1,31)
d2 = datetime(2007,1,31)

assert repr(d1) == repr(d2)
assert d1 is not d2
 


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().


Da gucke ich lieber debugger nach, da habe ich dann auch einen ganzen Haufen andere infos. Ich bin kein so großer Freund von Printlining.
BlackJack

Beitragvon BlackJack » Samstag 3. Februar 2007, 15:17

keppla hat geschrieben:
id() bringt dir garnix

Wenn ich wissen will, an _welches_ Objekt ein name gebunden ist, bringt mir das mehr als eine (möglicherweise gleich aussehende) Ausgabe eines __repr__. Das meinte ich auch mit eindeutiger:

Code: Alles auswählen

d1 = datetime(2007,1,31)
d2 = datetime(2007,1,31)

assert repr(d1) == repr(d2)
assert d1 is not d2
 


Tests auf Objektidentität ist nur in wenigen Fällen wirklich sinnvoll/interessant. Bei `datetime` fällt mir da überhaupt kein Grund ein. Werte und Typen sind eher interessant. Wobei ein nicht unbeträchtlicher Teil von Klassen `__repr()__` gar nicht überschreibt, man also Typ und Identität auf einmal bekommt.
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Beitragvon keppla » Samstag 3. Februar 2007, 18:18

Tests auf Objektidentität ist nur in wenigen Fällen wirklich sinnvoll/interessant.


Ich hatte das so aus der Beschreibung rausgelesen (welches objekt an einen namen gebunden ist).

Bei `datetime` fällt mir da überhaupt kein Grund ein.


Das war auch eher des Beispiels wegen, ich hab halt ne vorhandene Klasse gewählt.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Sonntag 4. Februar 2007, 08:53

keppla hat geschrieben:Ich hatte das so aus der Beschreibung rausgelesen (welches objekt an einen namen gebunden ist).
Das macht man aber nicht mit id sonder mit repr. Identität != Typ.

``id`` gibt mir einen kollisionsfreihen (Also wirklich einzigartige) Numerischen Wert zurück. Das ist die Identität des Objektes (BZW. Des namen der an Objekt X gebundene ist.).

Code: Alles auswählen

blex = BasisLexer("**//test**")
print id(blex) #id: 10374384


Falls zwei Objekte die gleiche id haben, muss das eine, eine Referenz auf das andere sein oder auf ein Objekt X das noch nicht untersucht wurde.

Was ist ``blex2``? Ist es das das instanziierte Objekt der Klasse ``BasisLexer`` oder ist es nur die Referenz auf ``blex``?

Code: Alles auswählen

   
    ref_blex = blex2
    print id(blex2) #id: 10374384
    print id(ref_blex) #id: 10374384
    # ref_blex == blex2

Tja, was sagte ich noch am Anfang? ``id`` gibt die Identität zurück? Das habe ich ja wohl ad absurdum geführt :lol: Eine Identität ist was einzigartiges, einmaliges. Das gilt für Objekte/Name in Python aber anscheinend nicht. Mal ernsthaft: Alles in Python ist nur eine Referenz.

Wie auch immer, es sollte nun klar sein worauf ich hinaus wollte.

...

So eine ``id`` bringt mich nicht wirklich weiter. Ich kann damit nur herausfinden das zwei Namen auf die gleiche Speicheradresse zeigen (Oder besser gesagt auf den gleichen Inhalt). -- Es ist also gerade brauchbar um zu testen ob zwei Objekte die gleiche Identität haben. Und wie oft muss man sowas testen?

Wie BlackJack schon sagt, für mich ist es relevant welche Werte ein Name hat und an welches Objekt es gebunden ist. Das alles kann ich mit ``repr`` rausfinden (Wenn ich ``__repr__`` selber Sinnvoll überladen habe):

Code: Alles auswählen

src = """** test **"""
dwlex = DauCMSWikiLexer(src)
print repr(dwlex)


Output:

Code: Alles auswählen

<dcmswlex.DauCMSWikiLexer: [[('MARKUP_BOLD', None), ('LITERAL', ' test '), ('MARKUP_BOLD', None)]]>


Und wenn du unbedingt auch zusätlich die ``id`` angezeigt habe willst, dann fügst du zusätzlich in ``__repr__`` ein ``id(self)`` hinzu, ...

Code: Alles auswählen

def __repr__(self):
        return "<%s.%s: %r @ ID: %d>" % (
            _NAME_OF_THIS_MODULE, self.__class__.__name__, self._token_stream,
            id(self)
        )


Output wäre z.B.:

Code: Alles auswählen

<dcmswlex.DauWikiLexer: [[('MARKUP_BOLD', None), ('LITERAL', ' test '), ('MARKUP_BOLD', None)]] @ ID: 10373328>


... das IMHO aber unnötig ist, da wie gesagt mehrere Namen auch die gleiche Identität (id) habe können, falls die besagten auf das instanziierte referenziert sind.

Wenn mich nur der Wert interessiert (Und ich ``__str__`` überladen habe), genügt nur ein einfaches ``print dwlex``.

Fazit für mich: Die Überladung von ``__repr__`` ist für mich genauso unersätzlich wie die Überladung von ``__str__``. ``repr()`` nutze ich ziemlich oft, wohingegen ich ``id`` so gut wie garnicht brauche.

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

Beitragvon sape » Sonntag 4. Februar 2007, 09:00

Hier noch ein Beispiel über ``id``.

Code: Alles auswählen

x = 1
y = 1
print "%d == %d" % (id(x), id(y)) # 9722488 == 9722488

;)

Ich referenzierte y nicht auf x, aber dennoch haben die die gleiche id. Warum? Weil in Python alle Objekte die den gleichen Wert haben, von Python auf die gleiche Adresse referenziert werden, um Redundanzen zu verhindern. [1]

Noch ein Beispiel:

Code: Alles auswählen

x = 1
y = 1
print "x: %d == y: %d" % (id(x), id(y))
x = 2
print "x: %d != y: %d" % (id(x), id(y))
y=2
print "x: %d == y: %d" % (id(x), id(y))


Code: Alles auswählen

x: 9722488 == y: 9722488
x: 9722476 != y: 9722488
x: 9722476 == y: 9722476


Es sollte nun klar sein, das ``id`` nicht besser ist als ``repr`` beim debugen.

lg

EDIT:
[1] Das gilt aber nur für imutable und nicht für mutable Objekte!!

Code: Alles auswählen

x = [1, 2, 3]
y = [1, 2, 3]
print "x: %d != y: %d" %(id(x), id(y))

Code: Alles auswählen

x: 10369464 != y: 10381392
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Sonntag 4. Februar 2007, 11:29

sape hat geschrieben:
keppla hat geschrieben:Ich hatte das so aus der Beschreibung rausgelesen (welches objekt an einen namen gebunden ist).
Das macht man aber nicht mit id sonder mit repr. Identität != Typ.

``id`` gibt mir einen kollisionsfreihen (Also wirklich einzigartige) Numerischen Wert zurück. Das ist die Identität des Objektes (BZW. Des namen der an Objekt X gebundene ist.).

Nein, die Identität des Objekts. Der Namen hat keine.

Falls zwei Objekte die gleiche id haben, muss das eine, eine Referenz auf das andere sein oder auf ein Objekt X das noch nicht untersucht wurde.

Kein Objekt ist eine Referenz auf ein anderes (außer es ist ein weakref-Objekt ;)), ein Objekt ist ein Objekt. Und was ist an einem Objekt, das noch nicht untersucht wurde, anders als an einem, das untersucht wurde? Wir sind hier nicht in der Quanteninformatik.

Tja, was sagte ich noch am Anfang? ``id`` gibt die Identität zurück? Das habe ich ja wohl ad absurdum geführt :lol: Eine Identität ist was einzigartiges, einmaliges. Das gilt für Objekte/Name in Python aber anscheinend nicht. Mal ernsthaft: Alles in Python ist nur eine Referenz.

Das ist, mit Verlaub gesagt, Schwachsinn. Du solltest mal [wiki]Objekte[/wiki] durchlesen.
Dann lieber noch Vim 7 als Windows 7.

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

Beitragvon birkenfeld » Sonntag 4. Februar 2007, 11:30

sape hat geschrieben:

Code: Alles auswählen

x = 1
y = 1
print "%d == %d" % (id(x), id(y)) # 9722488 == 9722488

;)

Ich referenzierte y nicht auf x, aber dennoch haben die die gleiche id. Warum? Weil in Python alle Objekte die den gleichen Wert haben, von Python auf die gleiche Adresse referenziert werden, um Redundanzen zu verhindern. [1]

Nein, es ist *das gleiche Objekt*. Deswegen hat es *die gleiche id*.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
BlackJack

Beitragvon BlackJack » Sonntag 4. Februar 2007, 11:51

birkenfeld hat geschrieben:Nein, es ist *das gleiche Objekt*. Deswegen hat es *die gleiche id*.


Ich weiss, der Duden macht diese Unterscheidung nicht mehr, aber "es ist das *selbe* Objekt" ist etwas stärker und deutlicher. IMHO.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Sonntag 4. Februar 2007, 11:58

BlackJack hat geschrieben:
birkenfeld hat geschrieben:Nein, es ist *das gleiche Objekt*. Deswegen hat es *die gleiche id*.


Ich weiss, der Duden macht diese Unterscheidung nicht mehr, aber "es ist das *selbe* Objekt" ist etwas stärker und deutlicher. IMHO.


Hast recht. Irgendwie hab ich den Unterschied zwischen den beiden nie richtig gelernt, ebenso wie bei "anscheinend" und "scheinbar" :D
Dann lieber noch Vim 7 als Windows 7.

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

Beitragvon sape » Sonntag 4. Februar 2007, 13:02

birkenfeld hat geschrieben:
Falls zwei Objekte die gleiche id haben, muss das eine, eine Referenz auf das andere sein oder auf ein Objekt X das noch nicht untersucht wurde.

Kein Objekt ist eine Referenz auf ein anderes (außer es ist ein weakref-Objekt ;)), ein Objekt ist ein Objekt. Und was ist an einem Objekt, das noch nicht untersucht wurde, anders als an einem, das untersucht wurde? Wir sind hier nicht in der Quanteninformatik.
Ok, ich dachte Namen werden auch als Objekt betrachtet, das es doch heißt dass alles in Python ein Objekt ist? Ist denn die Variabel x (Instanz von x= [1,2,3]) kein Objekt? Sind Namen keine Objekte?

birkenfeld hat geschrieben:
Tja, was sagte ich noch am Anfang? ``id`` gibt die Identität zurück? Das habe ich ja wohl ad absurdum geführt :lol: Eine Identität ist was einzigartiges, einmaliges. Das gilt für Objekte/Name in Python aber anscheinend nicht. Mal ernsthaft: Alles in Python ist nur eine Referenz.

Das ist, mit Verlaub gesagt, Schwachsinn. Du solltest mal [wiki]Objekte[/wiki] durchlesen.

Ja aber wenn ich folgendes habe:

Code: Alles auswählen

x = [1,2 ,3]
y = x
Dan ist doch y eine Referenz von x? Oder nicht? Und x ist doch auch ein Objekt, es sei den Namen sind keine Objekte ;)

EDIT2: Fehler berichtigt!
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Sonntag 4. Februar 2007, 13:10

Oder mal anders Birkenfeld.

Code: Alles auswählen

def edit(list_):
    list_.append("Keine Referenz?")

li = [1,2,3]
print li
edit(li)
print li


Code: Alles auswählen

[1, 2, 3]
[1, 2, 3, 'Keine Referenz?']


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

Beitragvon sape » Sonntag 4. Februar 2007, 13:21

http://www.ruby-lang.org/de/documentati ... om-python/

Alles ist ein Objekt, und Variablen sind Referenzen auf Objekte.


Ok, dann sind Namen (Variablen?) nur Referenzen auf Objekte (Klassen und ?) und selbst keine Objekte? 0_o Ich dachte immer das eine Instanz von einer Klasse auch ein Objekt darstellt und nicht eine Referenz auf die Klasse.

[wiki]Objekte[/wiki]
Wiki-Objekte hat geschrieben:Objekte haben außerdem:

*

keine oder mehrere Methoden (vom Typobjekt bereitgestellt)
*

keinen oder mehrere Namen


Was ist den eine Funktion in Python? Auch ein Objekt des Namensraumes "Modul"? Oder sind in gruden nur Klassen (Namensräume) nur Objekte und somit auch Module? Operatoren sind in Python schonmal keine Objekte, so wie in Ruby?

Sorry aber um so mehr ich über die Definition "Objekte bei Python" nachdenke um so inkonsistenter erscheint mir das.

Ich dachte **alles** ist ein Objekt in Python.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Sonntag 4. Februar 2007, 13:32

Schau dir mal http://bj.spline.de/download/names'n'objects.pdf an. Namen sind keine Objekte, Namen kannst du dir eher als Schnüre vorstellen, die an ein Objekt drangebunden werden. Ein Objekt kann zwar mehrere Namen haben, aber ein Name kann nur ein Objekt haben. Und außerdem kann ein Name nicht auf einen Namen zeigen, sondern immer nur auf das daran gebundene Objekt.

BlackJack hat geschrieben:Ganz wichtig ist die Trennlinie zwischen `Names` und `Objects`. Pfeile von Namen können nur auf die Objektseite zeigen, aber nie und nimmernicht auf einen anderen Namen!
My god, it's full of CARs! | Leonidasvoice vs Modvoice

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder