Seite 1 von 3

Verfasst: Mittwoch 31. Januar 2007, 17:13
von birkenfeld
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.

Verfasst: Mittwoch 31. Januar 2007, 17:16
von sape
Ups, stimmt ja.

lg

Verfasst: Samstag 3. Februar 2007, 14:50
von keppla
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.

Verfasst: Samstag 3. Februar 2007, 15:17
von BlackJack
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.

Verfasst: Samstag 3. Februar 2007, 18:18
von keppla
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.

Verfasst: Sonntag 4. Februar 2007, 08:53
von sape
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

Verfasst: Sonntag 4. Februar 2007, 09:00
von sape
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

Verfasst: Sonntag 4. Februar 2007, 11:29
von birkenfeld
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.

Verfasst: Sonntag 4. Februar 2007, 11:30
von birkenfeld
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*.

Verfasst: Sonntag 4. Februar 2007, 11:51
von BlackJack
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.

Verfasst: Sonntag 4. Februar 2007, 11:58
von birkenfeld
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

Verfasst: Sonntag 4. Februar 2007, 13:02
von sape
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!

Verfasst: Sonntag 4. Februar 2007, 13:10
von sape
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?']
?

Verfasst: Sonntag 4. Februar 2007, 13:21
von sape
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.

Verfasst: Sonntag 4. Februar 2007, 13:32
von Leonidas
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!

Verfasst: Sonntag 4. Februar 2007, 13:32
von birkenfeld
sape hat geschrieben:
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?
Nein, Namen sind keine Objekte, sondern Einträge in Namensräumen, die auf Objekte verweisen. (Der Namensraum ist natürlich ein Objekt (normalerweise ein Dictionary), und der String, der den Key im Namensraum bildet, auch.
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 ;)
x und y sind Namen und zeigen beide auf das Listenobjekt. y zeigt nicht auf den Namen x.

Verfasst: Sonntag 4. Februar 2007, 13:35
von birkenfeld
sape hat geschrieben:
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.
Eine Instanz ist ein Objekt. Der Name nicht. Deswegen gibt es ja z.b. id().
[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?
Funktionen sind Objekte. Funktionen in Modulen haben (zumindest) einen Namen, der im Namensraum des Moduls eingetragen ist, Methoden im Namensraum der Klasse.

Wo und wie sind in Ruby Operatoren Objekte?
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.
Ja, ist es auch. Du hast es nur nicht verstanden.

Oder meinst du, auch "if" und "import" sollen Objekte sein?

Verfasst: Sonntag 4. Februar 2007, 13:36
von Leonidas
sape hat geschrieben:

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?']
Das wundert dich jetzt nicht, oder?
Du hast eine Funktion edit(), die einen Namen nimmt, das daran gebundene Objekt an list_ bindet und dort dessen Funktion append() aufruft.
Gehen wir es mal durch: Du erstellst eine Liste, fein. Dann zeigst du die Liste an, danach wird das an li gebundene Objekt geändert (wobei es zwischenzeitlich einen zweiten Namen, list_, bekommt, der aber beim Beenden der Funktion zerstört wird). Dann Zeigst du das an, und siehst, dass das Objekt sich verändert hat. Wo ist da der Wiederspruch?

Verfasst: Sonntag 4. Februar 2007, 13:41
von sape
Ok, danke euch beiden. Das hilft mir dann schon mal weiter zum Verständnis.

Eine Frage ist aber noch offen:

Vorweg:
In C: ``int i = 0``
In C wäre i eine Variable vom Datentype int.

In C++ sind Instanzen von Klassen auch Variablen, werden aber halt Instanzen genant.

Daher die Frage: Sind den Namen in Python Variablen und instanzen?
Wiel für mich ist i in folgenden Code eine Instanz/Variabel (Wie auch immer. immer diese Unterscheidung zwischen Variabel und instanz) von Foo:

Code: Alles auswählen

class Foo(): pass
i = Foo()

Verfasst: Sonntag 4. Februar 2007, 13:52
von sape
birkenfeld hat geschrieben: Eine Instanz ist ein Objekt. Der Name nicht. Deswegen gibt es ja z.b. id().
Puh, nun wird es ansträngend:

Code: Alles auswählen

class Foo: pass
x = Foo()
Was ist x? Ist x die Instanz von Foo? Wenn ja dann ist x ein Objekt! x ist aber auch der Name der Instanz von Foo == x ist die Instanz von Foo.
birkenfeld hat geschrieben: Funktionen sind Objekte. Funktionen in Modulen haben (zumindest) einen Namen, der im Namensraum des Moduls eingetragen ist, Methoden im Namensraum der Klasse.
Funktionen sind also Objekte? Eine Funktion hat doch aber ein Namen. Eine Klasse hat auch ein Namen. Bei einer Klasse wird aber gesagt sie ist ein Objekt. Ok. Bei einer Funktion wird dann auch gesagt sie ist ein Objekt. Aber ein Instanz ist kein Objekt? Ne Moment, Du sagtest ja das Instanzen auch Objekte sind. Dan ist der Name x auch ein Objekt das an das Objekt Foo gebunden ist, weil x die Instanz von Foo ist?

Merkt keiner den Widerspruch, bzw. wie kleinkariert das eigentlich ist?
Ich möchte auch erklären warumd as kleinkariert ist.
Du sagst das Instanzen Objekte sind. Du sagt aber das Namen kein Objekte sind. Man kann aber nur über einen Namen eine Instanz erzeugen. So abld ich ``x = Foo()`` schreibe ist x eine Instanz und somit ein Objekt. Aber sobald ich sage das x der Name ist der an Foo gebunden ist, ist es kein Objekt mehr sondern nur ein Namen?
Wo und wie sind in Ruby Operatoren Objekte?
Per Definition ist alles in Ruby ein Objekt. Man kann wirklcih alles überladen.