Python-Unterschied zwischen Druckobjekt und Druckobj .__ str __ () [mindestens mit Unicode?]

9

Mir wurde gesagt, dass das Aufrufen von print obj obj.__str__() aufrufen würde, was wiederum eine Zeichenfolge zum Drucken an die Konsole zurückgeben würde. Jetzt habe ich ein Problem mit Unicode, wo ich keine nicht-ASCII-Zeichen drucken konnte. Ich habe das typische "Ascii out of range" Zeug.

Beim Experimentieren funktionierte Folgendes:

%Vor%

Mit beiden Funktionen genau so ( __str__() gibt nur self.__repr__() zurück). Was nicht funktioniert hat:

%Vor%

Das Problem trat nur auf, wenn ein Zeichen außerhalb des ASCII-Bereichs verwendet wurde. Die endgültige Lösung war in __str__() :

%Vor%

Jetzt funktioniert es für alle Teile. Meine Frage ist jetzt: Wo ist der Unterschied? Warum funktioniert es jetzt? Ich verstehe, wenn nichts funktioniert hat, warum das jetzt funktioniert. Aber warum funktioniert nur der obere Teil, nicht der untere.

OS ist Windows 7 x64 mit einer Standard-Windows-Eingabeaufforderung. Auch die Codierung wird als cp850 gemeldet. Dies ist eher eine allgemeine Frage, um Python zu verstehen. Mein Problem ist bereits gelöst, aber ich bin nicht 100% glücklich, vor allem, weil das Aufrufen von str(obj) eine Zeichenfolge ergibt, die nicht so codiert ist, wie ich es wollte.

%Vor%

Entferne die letzte obj und es funktioniert. Behalte es und es stürzt mit

ab %Vor%     
javex 03.07.2012, 19:26
quelle

2 Antworten

4

Ich vermute, dass der Ausdruck für ein Objekt obj , das gedruckt werden soll, etwa so aussieht:

  1. Überprüft, ob obj ein unicode ist. Wenn ja, codiert es in sys.stdout.encoding und druckt.
  2. Überprüft, ob obj ein str ist. Wenn ja, druckt es direkt.
  3. Wenn obj etwas anderes ist, ruft str(obj) auf und gibt das aus.

Schritt 1. Warum funktioniert print obj.__str__() in Ihrem Fall?

Nun, was str(obj) macht ist:

  1. Rufen Sie obj.__str__() .
  2. auf
  3. Wenn das Ergebnis ein str ist, gebe es zurück
  4. Wenn das Ergebnis ein unicode ist, wird es in "ascii" codiert und das
  5. zurückgegeben
  6. Ansonsten ist etwas größtenteils nutzlos.

Der Aufruf von obj.__str__() überspringt direkt die Schritte 2 und 3, weshalb Sie den Fehler bei der Codierung nicht erhalten.

Das Problem ist nicht darauf zurückzuführen, wie print funktioniert, sondern darauf, wie str() funktioniert. str() ignoriert sys.stdout.encoding . Da es nicht weiß, was Sie mit der resultierenden Zeichenfolge tun möchten, kann die Standardcodierung, die es verwendet, als willkürlich betrachtet werden. ascii ist so gut oder schlecht wie jede andere.

Um diesen Fehler zu vermeiden, stellen Sie sicher, dass Sie str von __str__() zurückgeben, wie es in der Dokumentation beschrieben ist. Ein Muster, das Sie für Python 2.x verwenden könnten, könnte sein:

%Vor%

(Wenn Sie sicher sind, dass Sie die str() -Darstellung nicht für das Drucken auf der Konsole benötigen).

    
millimoose 03.07.2012, 22:40
quelle
1

Wenn Sie sich zuerst die Online-Dokumentation ansehen, __str__ und __repr__ haben unterschiedliche Zwecke und sollten unterschiedliche Ergebnisse erzeugen. Daher ist es nicht die beste Lösung, __repr__ von __str__ aufzurufen.

Zweitens ruft print __str__ auf und erwartet keine nicht-ASCII-Zeichen, denn print kann nicht erraten, wie das nicht-ASCII-Zeichen konvertiert wird.

Schließlich ist __unicode__ in neueren Versionen von Python 2.x die bevorzugte Methode zum Erstellen einer Zeichenfolgendarstellung für ein Objekt. Es gibt eine interessante Erklärung in Python str im Vergleich zu Unicode .

Um die Frage wirklich zu beantworten und zu beantworten, könntest du so etwas tun wie:

%Vor%     
Rodrigue 03.07.2012 21:54
quelle

Tags und Links