OOP

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
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Dackel hat geschrieben:funktionalen Ecke
Das ist was ganz anderes: http://de.wikipedia.org/wiki/Funktional ... iersprache
Dackel
User
Beiträge: 11
Registriert: Mittwoch 4. März 2009, 20:44

Ich glaube, Du missverstehst mich.

Nicht alle, die an der Entwicklung von Python beteiligt waren, waren OO-Fetischisten. Wenn man von einer rein funktionalen Sprache kommt, wird man eher eine Funktionsapplikation à la

Code: Alles auswählen

len x
gewöhnt sein. Insofern können insbesondere zur Behandlung von Listentypen einiges schlicht aus der Gewohnheit von alten ML- oder Haskellprogrammierern gewachsen sein.
Aber da tiefer drüber zu diskutieren ist IMO sinnlos, es sei denn jemand, der direkt an der Entwicklung zu der Zeit beteiligt war, beantwortet es uns.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

r74 hat geschrieben:Aber ich glaube nicht, dass die Python-Entwickler ohne wirklichen Grund es einfach so gemacht haben, wie es im Moment ist.
Ja natürlich nicht, aber das war auch nicht deine Frage. Auf deine Frage ist die Antwort nunmal „Ist so“. Auch wenn es unbefriedigend ist. Aber es gibt einfach keinen zwingenden Grund warum man eine len()-Funktion nehmen musste.
BlackJack

@Darii: Vielleicht gab es doch zwingende Gründe. Zum Beispiel Zeichenketten. Ich glaube die waren nicht immer vollwertige Objekte. Deswegen auch die redundanten Funktionen im `string`-Modul, bevor die meisten Funktionen da drin zu Methoden auf `str` wurden. Die Länge von Zeichenketten zu ermitteln ist sicher wichtig, und wenn die keine Methode dafür haben können, braucht man halt mehr oder weniger zwingend eine Funktion. Man hätte natürlich auch ein Schlüsselwort oder einen Operator verwenden können. ;-)
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Darii hat geschrieben:Das Konzept von len(dass nach einer Methode __len__ bei dem Objekt gesucht wird) findest du in Python aber auch an anderen Stellen, z.B. bei "foo in bar" sucht Python nach einer Methode namens __contains__ von bar. Oder bei for(__getitem__ und __iter__ sind hier heiße Kandidaten).
Genauer gesagt wird bei der jeweiligen Klasse des Objekts gesucht, nicht bei der Instanz selbst.
Darii hat geschrieben:
numerix hat geschrieben:Ich empfinde hier auch Inkonsistenzen. Beispiel für eine Liste a:
Es heißt a.sort() und nicht sort(a), stattdessen gibt es z.B. sorted(a).
Das sind aber auch zwei verschiedene Funktionen. sort arbeitet in-place, sorted gibt eine neue Liste zurück und akzeptiert außerdem ein beliebiges iterable.
Ja, das ist typischerweise der Unterschied: Funktionen mutieren das übergebene Objekt nicht sondern geben ein neues zurück, Methoden mutieren das Objekt und geben None zurück. (Das ist keineswegs zwingend, aber oft so.)
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

bords0 hat geschrieben:Genauer gesagt wird bei der jeweiligen Klasse des Objekts gesucht, nicht bei der Instanz selbst.
Bis auf Descriptoren wird immer die normale Suchreihenfolge für die Attribute eingehalten, d.h. erst Instanz dann Klasse.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Blackjacks Erklärung zu `len` ist die richtige. Ein Uniformitätsprinzip ("Special cases aren't special enough to break the rules.") hätte ausgehend von einem objektorientierten Ansatz natürlich erfordert, dass alles dem "Object-Action"-Prinzip folgt und daher wäre etwas wie `foo.count()` konsequenter gewesen. Aber zu dem Zeitpunkt, wo immer mehr von Python objektorientiert wurde, war es offenbar schon zu spät und Rückwärtskompatibilität wurde noch höher bewertet als Uniformität.

Stefan

PS: Das __-Methoden nicht in Exemplaren gesucht werden sondern das man damit erst in der Klasse beginnt war auch mal eine Entscheidung in Python, die AFAIK hauptsächlich mit der Effizienz der Methodensuche zu tun hat.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

sma hat geschrieben:Aber zu dem Zeitpunkt, wo immer mehr von Python objektorientiert wurde, war es offenbar schon zu spät und Rückwärtskompatibilität wurde noch höher bewertet als Uniformität.
Vielleicht ja 2017 in Python 4. ;P Wobei es sich wohl empfehlen würde, bei ".len()" zu bleiben, da ".count()" schon existiert.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Jetzt machst du schon wieder den Fehler, kompatibel bleiben zu wollen :) Wenn schon, denn schon. Ein dict (oder allgemein Collections ohne weitere Eigenschaft) hat streng genommen keine Länge. Smalltalk wählte damals `size`, Objective-C etwas später `count` und ich finde, das ist der beste Kompromiss.

Stefan
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Darii hat geschrieben:
bords0 hat geschrieben:Genauer gesagt wird bei der jeweiligen Klasse des Objekts gesucht, nicht bei der Instanz selbst.
Bis auf Descriptoren wird immer die normale Suchreihenfolge für die Attribute eingehalten, d.h. erst Instanz dann Klasse.
Der Witz ist, dass bei "special syntax" (und len etc.) die Suche gleich bei der Klasse anfängt und nicht bei der Instanz. Die Attribute selbst kann man ganz normal nachschlagen.

Code: Alles auswählen

>>> list.__len__
<slot wrapper '__len__' of 'list' objects>
>>> len(list)
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
TypeError: object of type 'type' has no len()
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

bords0 hat geschrieben:Der Witz ist, dass bei "special syntax" (und len etc.) die Suche gleich bei der Klasse anfängt und nicht bei der Instanz.
Jein. Tatsachlich hast du Recht, das gilt aber nur für new-Style-Klassen. Naja, „Special cases aren't special enough to break the rules.“ hatten wir ja gerade...

Code: Alles auswählen

>>> list.__len__
<slot wrapper '__len__' of 'list' objects>
>>> len(list)
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
TypeError: object of type 'type' has no len()
Was willst du jetzt damit zeigen? Das kann sowieso gar nicht funktionieren, da list.__len__ keine Klassenmethode ist.
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Code: Alles auswählen

>>> list.__len__
<slot wrapper '__len__' of 'list' objects>
>>> len(list)
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
TypeError: object of type 'type' has no len()
Was willst du jetzt damit zeigen? Das kann sowieso gar nicht funktionieren, da list.__len__ keine Klassenmethode ist.[/quote]

Dass bei len nicht bei der Instanz (hier: list) nach dem Attribut __len__ gesucht wird.

Was Klassenmethoden damit zu tun haben, verstehe ich nicht :?:
len braucht doch keine Klassenmethoden (classmethod)?
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

bords0 hat geschrieben:Dass bei len nicht bei der Instanz (hier: list) nach dem Attribut __len__ gesucht wird.

Was Klassenmethoden damit zu tun haben, verstehe ich nicht :?:
len braucht doch keine Klassenmethoden (classmethod)?
Ganz einfach, da __len__ keine Klassenmethode ist, könne list.__len__() gar nicht funktionieren, wenn dort danach gesucht würde. Ich hab mir halt die Fehlermeldung nicht durchgelesen.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

bords0 hat geschrieben:Der Witz ist, dass bei "special syntax" (und len etc.) die Suche gleich bei der Klasse anfängt und nicht bei der Instanz. Die Attribute selbst kann man ganz normal nachschlagen.
Irgendwo muss man Kompromisse eingehen damit die Ausführungsgeschwindigkeit nicht völlig in den Keller geht.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Der Dict-Lookup mehr oder weniger bringt einen bei Python jetzt auch nicht um. ;) Sowas zu optimieren ist dann Aufgabe der VM und nicht der Sprache. Aber so ist das einfach nur inkonsistent.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Darii hat geschrieben:Der Dict-Lookup mehr oder weniger bringt einen bei Python jetzt auch nicht um. ;)
Doch, genau dies ist der Grund, warum Python vergleichsweise ineffizient ist und die UnloadenSwallow-Leute so Probleme haben, das System fix zu kriegen.
Darii hat geschrieben: Sowas zu optimieren ist dann Aufgabe der VM und nicht der Sprache. Aber so ist das einfach nur inkonsistent.
Eine VM kann da wenig machen. Bereits jetzt hat AFAIK CPython eine vtable pro Klasse, wo die ganzen Spezialmethoden, die ja überall aufgerufen werden müssen, eingetragen sind, damit man einen k*O(1) Zugriff mit minimalem k hat. Diese pro Exemplar einer Klasse mitzuschleppen klingt nicht nach einer guten Idee. Daher finde ich die Entscheidung, dass man Spezialmethoden nicht in einzelnen Exemplaren überschreiben kann, verständlich.

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

sma hat geschrieben:
Darii hat geschrieben:Der Dict-Lookup mehr oder weniger bringt einen bei Python jetzt auch nicht um. ;)
Doch, genau dies ist der Grund, warum Python vergleichsweise ineffizient ist und die UnloadenSwallow-Leute so Probleme haben, das System fix zu kriegen.
Aber Python ist ja nicht deswegen ineffizient, weil die fünf Spezialmethoden einen zusätzlichen dict-Lookup benötigen, sondern weil das überall der Fall ist.
Darii hat geschrieben: Sowas zu optimieren ist dann Aufgabe der VM und nicht der Sprache. Aber so ist das einfach nur inkonsistent.
Eine VM kann da wenig machen. Bereits jetzt hat AFAIK CPython eine vtable pro Klasse, wo die ganzen Spezialmethoden, die ja überall aufgerufen werden müssen, eingetragen sind, damit man einen k*O(1) Zugriff mit minimalem k hat. Diese pro Exemplar einer Klasse mitzuschleppen klingt nicht nach einer guten Idee.
Muss man ja auch nicht, so lange das Exemplar sie nicht enthält.
BlackJack

@Darii: Ich denke mal die "fünf" Spezielmethoden werden einfach *deutlich* öfter aufgerufen als Andere. Insofern macht das schon Sinn, deren Aufruf zu beschleunigen.
Antworten