Principle of Biggest Surprise
Ich bitte um Feedback zu meinem Artikel. Danke im vorraus.
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
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.
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.
Bücher und Tutorials müssten `__del__()` einfach nicht erwähnen, oder halt deutlich mit der Warnung versehen, welche Randbedingungen hier gelten.
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.
Bücher und Tutorials müssten `__del__()` einfach nicht erwähnen, oder halt deutlich mit der Warnung versehen, welche Randbedingungen hier gelten.
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.
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
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
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__()).
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__()).
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__()).
Zuletzt geändert von name am Sonntag 28. Juni 2009, 10:34, insgesamt 1-mal geändert.
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
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.
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
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
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
@name: Was meinst Du wie viele Leute von einer Laufzeitwarnung über unauflösbare Kreise überrascht wären und sich beschweren würden, dass sie die Warnung nicht haben wollen.
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.
`__del__()` in Python-Klassen nicht zu verwenden ist *die* Lösung. Wird von Java-Programmierern mit `finalize()` ja auch so gemacht. Die Methode ist ein Entwurfsfehler, der in beiden Sprachen mal gemacht wurde. Andererseits braucht man sie in Typen, die nicht in Python implementiert wurden, um Ressourcen wieder freigeben zu können, die nicht im Einflussbereich des Python-Interpretierers liegen.
Ich denke mal sollte `__del__()` einfach nicht implementieren, dann hat man auch keine Probleme mit Kreisbeziehungen. Deine neue "magic method", die das Problem beheben soll, geht ja noch mehr in Richtung manuelle Ressourcenverwaltung als man das mit `__del__()` sowieso schon tut, obwohl man damit ja meistens versuchen will etwas "automagisch" wieder freizugeben. Ich denke da ist es einfacher eine Methode zum Aufräumen explizit aufzurufen, oder mit ``with`` zu arbeiten.
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.
`__del__()` in Python-Klassen nicht zu verwenden ist *die* Lösung. Wird von Java-Programmierern mit `finalize()` ja auch so gemacht. Die Methode ist ein Entwurfsfehler, der in beiden Sprachen mal gemacht wurde. Andererseits braucht man sie in Typen, die nicht in Python implementiert wurden, um Ressourcen wieder freigeben zu können, die nicht im Einflussbereich des Python-Interpretierers liegen.
Ich denke mal sollte `__del__()` einfach nicht implementieren, dann hat man auch keine Probleme mit Kreisbeziehungen. Deine neue "magic method", die das Problem beheben soll, geht ja noch mehr in Richtung manuelle Ressourcenverwaltung als man das mit `__del__()` sowieso schon tut, obwohl man damit ja meistens versuchen will etwas "automagisch" wieder freizugeben. Ich denke da ist es einfacher eine Methode zum Aufräumen explizit aufzurufen, oder mit ``with`` zu arbeiten.
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.
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
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.
@name: Den kleinen aber feinen Unterschied verstehe ich nicht. Ist wohl zu fein.
@Defnull: Wenn man sich auf `__del__()` als deterministischen Destruktor verlässt, ist IMHO das Programm fehlerhaft. Es ist von der Sprache ja nicht einmal garantiert, dass `__del__()` überhaupt jemals aufgerufen wird. Und Dateideskriptoren können ganz real schneller knapp werden, als die Speicherbereinigung mit dem Abräumen von Objekten hinterherkommt. Habe ich bei Java schon erlebt.
Wobei ich jetzt nicht sehe, warum der Container unbedingt eine `__del__()`-Methode braucht!? Wenn der keine hat, kann er ja problemlos abgeräumt werden und schon ist die Kreisbeziehung Container<->SeqAlg gelöst.
@Defnull: Wenn man sich auf `__del__()` als deterministischen Destruktor verlässt, ist IMHO das Programm fehlerhaft. Es ist von der Sprache ja nicht einmal garantiert, dass `__del__()` überhaupt jemals aufgerufen wird. Und Dateideskriptoren können ganz real schneller knapp werden, als die Speicherbereinigung mit dem Abräumen von Objekten hinterherkommt. Habe ich bei Java schon erlebt.
Wobei ich jetzt nicht sehe, warum der Container unbedingt eine `__del__()`-Methode braucht!? Wenn der keine hat, kann er ja problemlos abgeräumt werden und schon ist die Kreisbeziehung Container<->SeqAlg gelöst.
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.
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
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.
Ich denke ja immernoch persönlich, dass _del_ seine Einsatzberechtigung in seiner momentanen Form hat.
Ich würde gerne mal nachschauen, ob die Entwickler von Python es irgendwie einsetzen. Ich würde wetten! Manchmal sollen eben Sachen passieren, direkt nachdem der GC das Objekt weggeräumt hat. Nicht bei der Dereferenzierung, sondern wirklich beim wegräumen vom Garbage Collecter. Nur als normaler Programmierer, der keine Sprache entwickeln will, brauch man diesen Fall selten bis nie.
Man könnte noch eine Dereferenzierungsoperation einbauen. Aber was ist, wenn ein Objekt 2 Referenzen hat? Wird der dann 2mal aufgerufen?
Garbage Collecter sind halt für solche Fälle nicht so gut. Aber es gibt genug andere Wege, das zu umgehen. Deswegen is's für mich kein Problem.
Ich würde gerne mal nachschauen, ob die Entwickler von Python es irgendwie einsetzen. Ich würde wetten! Manchmal sollen eben Sachen passieren, direkt nachdem der GC das Objekt weggeräumt hat. Nicht bei der Dereferenzierung, sondern wirklich beim wegräumen vom Garbage Collecter. Nur als normaler Programmierer, der keine Sprache entwickeln will, brauch man diesen Fall selten bis nie.
Man könnte noch eine Dereferenzierungsoperation einbauen. Aber was ist, wenn ein Objekt 2 Referenzen hat? Wird der dann 2mal aufgerufen?
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.
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
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
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
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
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.
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.
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.