Seite 1 von 1
Neues String Formatting: Bug oder Feature?
Verfasst: Dienstag 21. September 2010, 05:05
von snafu
Weiß jemand, ob dies gewolltes Verhalten ist?
Code: Alles auswählen
>>> class Ham(object):
... def egg(self):
... return 'spam'
...
>>> ham = Ham()
>>> 'i love {ham.egg()}'.format(ham=ham)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Ham' object has no attribute 'egg()'
Der Attributzugriff ohne Methodenaufruf funktioniert wie erwartet:
Code: Alles auswählen
>>> 'i love {ham.egg}'.format(ham=ham)
'i love <bound method Ham.egg of <__main__.Ham object at 0xb7781bac>>'
Re: Neues String Formatting: Bug oder Feature?
Verfasst: Dienstag 21. September 2010, 06:18
von Pekh
Ich denke, es ist schlicht nicht vorgesehen, an dieser Stelle Funktionsaufrufe zu platzieren. Wenn du den Wert über einen Funktionsaufruf ermitteln willst, gehört dieser in den .format() - Teil.
Re: Neues String Formatting: Bug oder Feature?
Verfasst: Dienstag 21. September 2010, 08:12
von snafu
Naja, wie gesagt, mit Attributen und Dict-Schlüsseln funktioniert es. Ich sehe jetzt nicht, inwiefern zum Beispiel ein `"Hello, {name.title()}"` etwas soviel anderes ausmacht, dass es da nicht rein soll/darf. Aber gut, dass ist natürlich hier nicht der Ort, an dem solche Dinge Gehör finden würden. Ich war nur etwas irritiert von der Fehlermeldung. Ganz offensichtlich trennt der Parser die Klammern nicht vom Namen.
Re: Neues String Formatting: Bug oder Feature?
Verfasst: Dienstag 21. September 2010, 08:21
von Leonidas
Wenn du den Wert errechnen willst nimmst du ein Property. Ansonsten ist die Überlegung wohl, dass die Strings nicht irgendwelche Beliebigen Funktionsaufrufe machen sollen, weil zu viel Programmlogik reinkommen könnte, wie bei den Django-Templates auch.
Re: Neues String Formatting: Bug oder Feature?
Verfasst: Dienstag 21. September 2010, 08:32
von snafu
Na klar, an die Programmlogik hatte ich auch schon gedacht. Meist ist der Rückgabewert einer Funktion ja nicht unbedingt etwas, dass man in einen String setzen möchte. Trotzdem eine merkwürdige Entscheidung, wie ich finde. An anderen Stellen bevormundet einen Python ja auch nicht mit Konzepten, deren Tenor mehr oder weniger ist: "Lieber nicht, sonst machst du noch was kaputt". Ausgenommen natürlich die Speicherverwaltung, aber das ist ein ganz anderes Thema und dort ist es auch gut, so wie es ist.
Aber natürlich ist es auch denkbar, dass die Entwickler einfach nicht Funktionsaufrufe in die Planung einbezogen haben.
Re: Neues String Formatting: Bug oder Feature?
Verfasst: Dienstag 21. September 2010, 09:28
von mkesper
PEP 3101 hat geschrieben: Unlike some other programming languages, you cannot embed arbitrary
expressions in format strings. This is by design - the types of
expressions that you can use is deliberately limited. Only two operators
are supported: the '.' (getattr) operator, and the '[]' (getitem)
operator. The reason for allowing these operators is that they don't
normally have side effects in non-pathological code.
Re: Neues String Formatting: Bug oder Feature?
Verfasst: Dienstag 21. September 2010, 09:52
von lunar
@snafu: Das ist eine nachvollziehbare, sinnvolle und begründbare Entscheidung, die nichts mit „Bevormunden“ zu tun hat. Es geht schlicht darum, welchem Zweck die Formatierung von Zeichenketten dienen soll, und wo man die Grenzen der Formatierungssprachen setzt. Python setzt diese Grenze genau an der Grenze zwischen den Daten eines Objekts (einfache Attribute, Eigenschaften und Schlüssel) und dessen Verhalten (Methoden), somit dient die Formatierung von Zeichenketten einzig und allein der Darstellung von Daten.
Ich finde das sinnvoll, denn denn die bloße Umwandlung von Daten in eine andere Repräsentation sollte keine Seiteneffekte haben. Methoden haben in der Regel Seiteneffekte zum Zweck, während Eigenschaften, Schlüssel und Attribute keine Seiteneffekte haben (sollten) [1]. Außerdem gibt es für das Verhalten von Objekten schließlich den "normalen" Quelltext, und man sieht an PHP, wo man hinkommt, wenn man die Sprache zur Zeichenkettenformatierung zur vollwertigen Programmiersprache aufbläst.
Natürlich kann man auch an anderen Stellen Grenzen ziehen, aber die Grenze zwischen Daten und Verhalten ist meines Erachtens eben die offensichtlichste. Würde man dagegen Methodenaufrufe erlauben, dann käme man logischerweise zu den Argumenten von Methoden, und würde dann bei kompletten Ausdrücken enden.
Davon abgesehen macht man imho was falsch, wenn man an dieser Stelle Methoden aufrufen möchte. Wäre die Methode so unmittelbar zur Formatierung gedacht, dann sollte sie eine Eigenschaft sein, wenn nicht, also wenn das Ziel des Aufruf eigentlich der von der Methode hervorgerufene Seiteneffekt ist, was hat die Methode dann in der Formatierung einer Zeichenkette zu suchen?
[1] Natürlich kann man theoretisch auch in einer Eigenschaft oder in __getitem__ Seiteneffekte hervorrufen, aber nicht in gutem Quelltext.
Re: Neues String Formatting: Bug oder Feature?
Verfasst: Dienstag 21. September 2010, 09:58
von BlackJack
@snafu: Die Zeichenketten in die man hinein"format"ieren kann, sind ja nicht immer Konstanten im Programm, die können ja selbst schon aus Benutzereingaben entstanden sein. Und dann wäre `format()` potentiell so gefährlich wie `eval()` wenn da beliebiger Quelltext stehen dürfte und ausgeführt wird.
Solche "code injektions" gar nicht erst zu erlauben, würde ich nicht als bevormunden ansehen. Das ist einfach eine zu grosse Sicherheitslücke als dass man sie offen stehen lassen sollte.
Re: Neues String Formatting: Bug oder Feature?
Verfasst: Mittwoch 22. September 2010, 15:04
von snafu
lunar hat geschrieben:Wäre die Methode so unmittelbar zur Formatierung gedacht, dann sollte sie eine Eigenschaft sein, wenn nicht, also wenn das Ziel des Aufruf eigentlich der von der Methode hervorgerufene Seiteneffekt ist, was hat die Methode dann in der Formatierung einer Zeichenkette zu suchen?
Es gibt imho schon einige Anwendungsbereiche, wo eine Methode nichts am Exemplar verändert, sondern lediglich etwas zurückgibt. Man denke nur an diverse PyQt-Konvertierungsmethoden oder an die schon angeschnittenen Methoden auf Zeichenketten in Python.
BlackJack hat geschrieben:Solche "code injektions" gar nicht erst zu erlauben, würde ich nicht als bevormunden ansehen. Das ist einfach eine zu grosse Sicherheitslücke als dass man sie offen stehen lassen sollte.
Naja, aber das ist es doch, was "Bevormundung" normalerweise bedeutet. Man fällt die Entscheidung für jemand anderen oder nimmt ihm generell die Entscheidungsfreiheit auf bestimmten Gebieten, weil man glaubt, dass sei das beste für ihn und würde ihn vor Gefahren schützen. Eine Warnung in der Doku hätte hier m.E. ausgereicht. Wie dem auch sei. Ich habe jetzt nicht vor, im großen Stil eine Lanze für die Implementierung von Methodenaufrufen zu brechen...
Re: Neues String Formatting: Bug oder Feature?
Verfasst: Mittwoch 22. September 2010, 15:12
von Rebecca
BlackJack hat geschrieben:Und dann wäre `format()` potentiell so gefährlich wie `eval()` wenn da beliebiger Quelltext stehen dürfte und ausgeführt wird.
Snafu, damit du deine Methodenaufrufe haben koenntest, wuerde fuer uns andere format unbenutzbar...
Re: Neues String Formatting: Bug oder Feature?
Verfasst: Mittwoch 22. September 2010, 15:26
von snafu
Potenziell gefährlich ist es auch, dass Attribute theoretisch Properties sein können, womit sich genau so viel Schaden anrichten lässt.
Re: Neues String Formatting: Bug oder Feature?
Verfasst: Mittwoch 22. September 2010, 15:43
von Rebecca
Aber dann sind es nur die Getter-Methoden die aufgerufen werden. Sollte jedem klar sein dass es eine schlechte Idee ist, da wilde Sachen drin zu machen...
Re: Neues String Formatting: Bug oder Feature?
Verfasst: Mittwoch 22. September 2010, 16:10
von BlackJack
@snafu: Zudem unterliegen die "getter" der Kontrolle des Programmierers. Die werden nicht vom Angreifer definiert, der die Injection versucht.
Ein gewisser Satz Regeln der das Zusammenleben ermöglicht, ist nicht das selbe wie Bevormundung. Oder findest Du es als Bevormundung, dass in den meisten Staaten/Gemeinschaften nicht einfach jeder von jedem erschossen werden darf und nicht überall Waffen und Munition herumliegen? Wenn das was Du möchtest möglich wäre, dann wäre Python noch unsicherer als ein schlecht konfigurierter Webserver mit PHP.
Re: Neues String Formatting: Bug oder Feature?
Verfasst: Samstag 25. September 2010, 19:06
von lunar
@snafu: Deine Beispiele und Deine Argumentation sind nicht überzeugend, und ich glaube, dass weißt Du auch selbst.
Deine Beispiele beziehen sich auf Ausnahmen. Unveränderliche Typen sind nicht die Regel, sondern sowohl in der Standardbibliothek als auch in Drittbibliotheken Sonderfälle. Ebenso sind automatisch generierte Anbindungen an C++-Bibliotheken keine guten Beispiele für die Idiomatik und den Ausdruck der Sprache Python, zumal C++ gar keine Eigenschaften kennt und somit zwischen Daten und Verhalten gar nicht so klar trennen kann wie Python.
Deine Argumentation zieht sich folglich an Sonderfällen und Ausnahmen hoch. Sie ist gar nicht falsch, es hat ja niemand bestritten, dass man Methoden ohne Seiteneffekte ebenso implementieren kann wie Eigenschaften mit Seiteneffekten. Beides kommt in der Realität möglicherweise auch gar nicht so selten vor.
Dennoch sind und bleiben es eben Sonderfälle. Meist haben Methoden Seiteneffekte, denn andernfalls könnte man sie ja gleich in Eigenschaften oder gar triviale Attribute umwandeln. Eigenschaften mit nicht-trivialen (e.g. Caching) Seiteneffekten sind nicht einmal guter Quelltext, und können somit eigentlich gar nicht in Betracht gezogen werden.
Re: Neues String Formatting: Bug oder Feature?
Verfasst: Samstag 25. September 2010, 19:28
von birkenfeld
snafu hat geschrieben:
BlackJack hat geschrieben:Solche "code injektions" gar nicht erst zu erlauben, würde ich nicht als bevormunden ansehen. Das ist einfach eine zu grosse Sicherheitslücke als dass man sie offen stehen lassen sollte.
Naja, aber das ist es doch, was "Bevormundung" normalerweise bedeutet. Man fällt die Entscheidung für jemand anderen oder nimmt ihm generell die Entscheidungsfreiheit auf bestimmten Gebieten, weil man glaubt, dass sei das beste für ihn und würde ihn vor Gefahren schützen. Eine Warnung in der Doku hätte hier m.E. ausgereicht. Wie dem auch sei. Ich habe jetzt nicht vor, im großen Stil eine Lanze für die Implementierung von Methodenaufrufen zu brechen...
Ich glaube, das wurde schon genannt, aber nochmal zur Betonung: Die Implementierung von Aufrufen würde wahrscheinlich den vorhandenen Code für das Formatting verdoppeln. Denn genauso wenig wie du einen Grund siehst, keine Aufrufe zu erlauben, werden andere Leute keinen Grund sehen, diese nur ohne Argumente zu erlauben. Und Pythons Aufrufsyntax nachzuimplementieren ist durchaus aufwendig (ganz abgesehen von dem Problem, aus welchem Namespace die Argumentwerte kommen).
Was dann für Aufrufe gilt, gilt genauso für beliebige Expressions. Und so weiter, bis wir gleich eval() verwenden könnten.
Und da find ich die Beschränkung, so wie sie jetzt ist, noch am sinnvollsten.
Re: Neues String Formatting: Bug oder Feature?
Verfasst: Sonntag 26. September 2010, 11:11
von snafu
Gut, und letztlich gibt es auch schon einen Haufen Template-Engines, die man bei Bedarf benutzen könnte.