Principle of Biggest Surprise
Verfasst: Samstag 27. Juni 2009, 15:53
Ich bitte um Feedback zu meinem Artikel. Danke im vorraus.
Seit 2002 Diskussionen rund um die Programmiersprache Python
https://www.python-forum.de/
Wenn copy.copy das Original zurueckgibt is das ne Ueberraschung. Da is eine Exception besser.BlackJack hat geschrieben:Also `copy.copy()` ist IMHO keine "Überraschung". Oder zumindest eine bei der es nicht überraschend ist, dass es Leute überraschen *muss*, *egal* wie man es konkret implementiert. Einige sind überrascht, dass bei einer Liste nur eine flache Kopie gemacht wird, andere, dass die Kopie bei Klassen *noch* flacher ist.
Ich meinte eine Warnung zur Laufzeit das man einen unloesbaren Referenzkreis hat.BlackJack hat geschrieben:Bei `__del__()` stimmt die Behauptung mit der fehlenden Warnung nicht. Die Dokumentation beschreibt das durchaus und hat auch einen extra hervorgehobenen Textkasten. Das grosse Problem hier sind IMHO so tolle Bücher wie das OpenBook von Galileo, die nicht nur die Warnung nicht wiedergeben, sondern auch noch so tun, als sei `__del__()` eine nützliche Methode für Python-Objekte. Das ist sie nun einmal nicht.
Also einfach ned verwenden? Ist finde ich auch keine Loesung.BlackJack hat geschrieben:Bücher und Tutorials müssten `__del__()` einfach nicht erwähnen, oder halt deutlich mit der Warnung versehen, welche Randbedingungen hier gelten.
Eigentlich wird ja typestruct->tp_str aufgerufen, sonst waer das ganze ja sinnlos. Gerade *das* es der einzige Platz ist, macht es so schlimm. Waer alles lookup in der Klasse, was solls.str1442 hat geschrieben:Die Geschichte mit str() und anderen "magic methods" ist wirklich suboptimal, dürfte aber der einzige Platz sein, an welchen explizit in der Klasse nachgeschaut wird (und Class.__str__(inst) aufgerufen wird statt inst.__str__()).
Was ja nicht geht, weil der struct lookup __getattribute__ umgeht.DasIch hat geschrieben:Das mit der Auflösung der Magic Methods würde mich jetzt nicht so stören wenn man dass über Metaklassen beeinflussen könnte.
Mein Vorschlag waere eine Magic-Method die wenn bei einem Objekt im Cycle vorhanden die Objekte in der Reihenfolge in der sie deallokiert werden sollen zurueckgibt, nur das is noch nicht ganz durchgedacht.str1442 hat geschrieben:Zu __del__: Java hat das gleiche Problem mit der Methode finalize(), von der auch abgeraten wird. Die Implementierung von __del__ hat ganz gewaltige Probleme mit dem GC, und anscheinend sind die nicht einfach zu lösen. Siehe hier: http://de.wikipedia.org/wiki/Garbage_Co ... alisierung
Wenn dem so ist implementiert CPython Python falsch. Weil ja __getattribute__ (der metacls) etc ignoriert werden. Also wirds ned direkt in der Klasse nachgeschlagen, hoechstens direkt im Klassen-Dict. (kleiner, aber wichtiger Unterschied)BlackJack hat geschrieben:Magic Methods werden "eigentlich" in der Klasse nachgeschlagen. Das ist die Ebene auf der Python's Semantik definiert ist. ``typestruct->tp_str`` ist kein Python und findet sich so sicher auch nicht in Jython oder IronPython wieder. Das ist ein Implementierungsdetail von CPython.
Ich habe Objekte (SeqAlg) die an einen offenen File-Pointer gebunden sein müssen. Außerdem habe ich einen Container, die viele dieser SeqAlg Instanzen vorhält und deshalb Referenzen zu ihnen hat. Außerdem möchte ich einer SeqAlg Instanzen erlauben, sich selbst zu manipulieren und daraus neue SeqAlg Instanzen (mit neuen File-Pointern) zu erschaffen, die wiederum in den Container eingepflegt werden müssen. Dafür brauch ich die Referenz zum Container im SeqAlg Objekt. SeqAlg braucht __del__() für das fp.close(). Wie mache ich sinnvoll das ohne __del__ oder ohne Kreisabhängigkeiten?BlackJack hat geschrieben:`__del__()` in Python-Klassen nicht zu verwenden ist *die* Lösung.
Wenn die metaclass __getattribute__ ueberschreibt ist dict-lookup ned unbedingt das selbe wie lookup in der Klasse.BlackJack hat geschrieben:@name: Den kleinen aber feinen Unterschied verstehe ich nicht. Ist wohl zu fein.
Dafür ist der direkte Zugriff über die C-Datenstruktur wahrscheinlich um Welten schneller als ein teurer Aufruf einer Python-Methode. Die Entscheidung, den Zugriff direkt zu implementieren, trägt einer Realität Rechnung, in der Szenarien, in denen diese Methoden aufgerufen werden, weitaus häufiger sind als solche, in denen diese Methoden über __getattribute__ manipuliert werden müssten, und ist daher durchaus nachvollziehbar und meiner Meinung nach auch sinnvoll.name hat geschrieben:Was ja nicht geht, weil der struct lookup __getattribute__ umgeht.DasIch hat geschrieben:Das mit der Auflösung der Magic Methods würde mich jetzt nicht so stören wenn man dass über Metaklassen beeinflussen könnte.
Code: Alles auswählen
>>> class A(object):
... pass
...
>>> a = A()
>>> b = a
>>> a is b
True
>>> del a
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> b
<__main__.A object at 0x00AAD7F0>
>>> del b
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined
Es ging darum zu zeigen, dass es eben nicht in der Klasse, sondern wo anders, gelookupt wird, anders als BlackJack behauptet hat.lunar hat geschrieben:Dafür ist der direkte Zugriff über die C-Datenstruktur wahrscheinlich um Welten schneller als ein teurer Aufruf einer Python-Methode. Die Entscheidung, den Zugriff direkt zu implementieren, trägt einer Realität Rechnung, in der Szenarien, in denen diese Methoden aufgerufen werden, weitaus häufiger sind als solche, in denen diese Methoden über __getattribute__ manipuliert werden müssten, und ist daher durchaus nachvollziehbar und meiner Meinung nach auch sinnvoll.name hat geschrieben:Was ja nicht geht, weil der struct lookup __getattribute__ umgeht.DasIch hat geschrieben:Das mit der Auflösung der Magic Methods würde mich jetzt nicht so stören wenn man dass über Metaklassen beeinflussen könnte.
Trotzdem, wenn in der Klasse, dann alles. Wenn nicht in der Klasse, dann nichts. Ich bleib dabei.lunar hat geschrieben:Mir ging es um den konkreten Kritikpunkt in deinem Artikel. Deswegen habe ich auch einen Satz zitiert, der vor der Diskussion mit BlackJack über den Attributzugriff fiel
Dann doch alles in der klasse, da spart man sich dann noch viele hashtables.lunar hat geschrieben:Ich hätte mir denken können, dass du dabei bleibst ... ich persönlich halte es für eine unschöne, aber eben notwendige Entwurfsentscheidung zugunsten einer höheren Ausführungsgeschwindigkeit.