Frage

In letzter Zeit hatte ich viel Probleme mit __repr__(), format(), und Codings. Sollte die Ausgabe von __repr__() codiert werden oder eine Unicode -Zeichenfolge sein? Gibt es eine beste Codierung für das Ergebnis von __repr__() in Python? Was ich ausgeben möchte, hat keine ASCII-Zeichen.

Ich verwende Python 2.x und möchte Code schreiben, der leicht an Python 3. Das Programm verwendet

# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function  # The 'Hello' literal represents a Unicode object

Hier sind einige zusätzliche Probleme, die mich gestört haben, und ich suche eine Lösung, die sie löst:

  1. Das Drucken eines UTF-8-Terminals sollte funktionieren (ich habe sys.stdout.encoding einstellen UTF-8, aber es wäre am besten, wenn auch andere Fälle funktionieren).
  2. Die Ausgabe in eine Datei (in UTF-8 codiert) sollte funktionieren (in diesem Fall, sys.stdout.encoding ist None).
  3. Mein Code für viele __repr__() Funktionen haben derzeit viele return ….encode('utf-8'), und das ist schwer. Gibt es etwas Robustes und Leichteres?
  4. In einigen Fällen habe ich sogar hässliche Bestien wie return ('<{}>'.format(repr(x).decode('utf-8'))).encode('utf-8'), dh die Darstellung von Objekten ist dekodiert, in eine formatierende Zeichenfolge eingebaut und dann neu eingestuft. Ich möchte solche verschlungenen Transformationen vermeiden.

Was würden Sie empfehlen, um einfach zu schreiben? __repr__() Funktionen, die sich in Bezug auf diese Codierungsfragen gut verhalten?

War es hilfreich?

Lösung

In Python2, __repr__ (und __str__) muss ein String -Objekt zurückgeben, kein Unicode -Objekt. In Python3 ist die Situation umgekehrt, __repr__ und __str__Muss Unicode -Objekte zurückgeben, nicht Byte (nee String) -Objekte:

class Foo(object):
    def __repr__(self):
        return u'\N{WHITE SMILING FACE}' 

class Bar(object):
    def __repr__(self):
        return u'\N{WHITE SMILING FACE}'.encode('utf8')

repr(Bar())
# ☺
repr(Foo())
# UnicodeEncodeError: 'ascii' codec can't encode character u'\u263a' in position 0: ordinal not in range(128)

In Python2 haben Sie keine Wahl. Sie müssen eine Codierung für den Rückgabewert von auswählen __repr__.

Haben Sie übrigens die gelesen Printfails wiki? Es kann Ihre anderen Fragen möglicherweise nicht direkt beantworten, aber ich fand es hilfreich, um zu beleuchten, warum bestimmte Fehler auftreten.


Beim Benutzen from __future__ import unicode_literals,

'<{}>'.format(repr(x).decode('utf-8'))).encode('utf-8')

kann einfacher geschrieben werden als

str('<{}>').format(repr(x))

Annahme str kodiert zu utf-8 auf Ihrem System.

Ohne from __future__ import unicode_literals, Der Ausdruck kann geschrieben werden als:

'<{}>'.format(repr(x))

Andere Tipps

Ich denke, ein Dekorateur kann es schaffen __repr__ Inkompatibilitäten auf vernünftige Weise. Hier ist, was ich benutze:

from __future__ import unicode_literals, print_function
import sys

def force_encoded_string_output(func):

    if sys.version_info.major < 3:

        def _func(*args, **kwargs):
            return func(*args, **kwargs).encode(sys.stdout.encoding or 'utf-8')

        return _func

    else:
        return func


class MyDummyClass(object):

    @force_encoded_string_output
    def __repr__(self):
        return 'My Dummy Class! \N{WHITE SMILING FACE}'

Ich benutze eine Funktion wie Folgendes:

def stdout_encode(u, default='UTF8'):
    if sys.stdout.encoding:
        return u.encode(sys.stdout.encoding)
    return u.encode(default)

Dann meine __repr__ Funktionen sehen so aus:

def __repr__(self):
    return stdout_encode(u'<MyClass {0} {1}>'.format(self.abcd, self.efgh))
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top