2014-09-24 25 views
5

ich diesen Code Teil einer Funktion, die schlecht fremde Zeichen aus einem String codiert Replace:Python 3.4: str: Attribute: ‚str‘ Objekt hat kein Attribut ‚dekodieren

s = "String from an old database with weird mixed encodings" 
s = str(bytes(odbc_str.strip(), 'cp1252')) 
s = s.replace('\\x82', 'é') 
s = s.replace('\\x8a', 'è') 
(...) 
print(s) 
# b"String from an old database with weird mixed encodings" 

Ich brauche hier ein„echten "Zeichenfolge, keine Bytes. Aber whend ich sie entschlüsseln will, muss ich eine Ausnahme:

s = "String from an old database with weird mixed encodings" 
s = str(bytes(odbc_str.strip(), 'cp1252')) 
s = s.replace('\\x82', 'é') 
s = s.replace('\\x8a', 'è') 
(...) 
print(s.decode("utf-8")) 
# AttributeError: 'str' object has no attribute 'decode' 
  • Wissen Sie, warum s Bytes hier ist?
  • Warum kann ich es nicht zu einer echten Zeichenfolge dekodieren?
  • Wissen Sie, wie man es sauber macht? (heute sende ich zurück [2:] [: - 1]. Arbeiten aber sehr hässlich, und ich möchte dieses Verhalten verstehen)

Vielen Dank im Voraus!

EDIT:

pypyodbc in python3 Unicode als Standard verwenden. Das hat mich verwirrt. Beim Verbinden können Sie ihm sagen, dass er ANSI verwenden soll.

con_odbc = pypyodbc.connect("DSN=GP", False, False, 0, False) 

Dann kann ich die zurückgegebenen Stoffe in CP850 wandeln, die die anfängliche Codepage der Datenbank vorhanden ist.

str(odbc_str, "cp850", "replace") 

Keine Notwendigkeit mehr manuell die jedes Sonderzeichen ersetzen. Vielen Dank pepr

+1

'str.decode' existiert nicht mehr in 3.x. Siehe https://docs.python.org/3/howto/unicode.html für den Umgang mit Strings und Bytes in 3.x – jonrsharpe

+1

'decode' dient zum Konvertieren von Bytes in abstrakte Zeichen, die den String bilden. Die Zeichenfolge in Python 3 enthält nur gültige Zeichen. Dies ist der Grund dafür, dass ".decode" nicht vorhanden ist - es gibt keine Bytes in einer Python 3-Zeichenfolge. – pepr

Antwort

2

Die gedruckte b"String from an old database with weird mixed encodings" ist nicht die Darstellung des Zeichenfolge Inhalt. Es ist der Wert des String-Inhalts. Da Sie nicht die Codierung Argument str() bestanden hat ... (siehe doc https://docs.python.org/3.4/library/stdtypes.html#str)

If neither encoding nor errors is given, str(object) returns object.__str__() , which is the “informal” or nicely printable string representation of object. For string objects, this is the string itself. If object does not have a __str__() method, then str() falls back to returning repr(object) .

Dies ist, was in Ihrem Fall passiert ist. Die b" sind tatsächlich zwei Zeichen, die den Teil des Zeichenfolge-Inhalts sind. Sie können auch versuchen:

s1 = 'String from an old database with weird mixed encodings' 
print(type(s1), repr(s1)) 
by = bytes(s1, 'cp1252') 
print(type(by), repr(by)) 
s2 = str(by) 
print(type(s2), repr(s2)) 

und er druckt:

<class 'str'> 'String from an old database with weird mixed encodings' 
<class 'bytes'> b'String from an old database with weird mixed encodings' 
<class 'str'> "b'String from an old database with weird mixed encodings'" 

Dies ist der Grund, warum s[2:][:-1] für Sie arbeitet.

Wenn Sie denken mehr darüber, dann ist (meiner Meinung nach) oder mögen Sie bytes oder bytearray aus der Datenbank (falls möglich) zu bekommen, und das Bytes zu beheben (siehe bytes.translate https://docs.python.org/3.4/library/stdtypes.html?highlight=translate#bytes.translate) oder Sie erfolgreich das bekommen string (mit Glück, dass beim Erstellen dieser Zeichenfolge keine Ausnahme aufgetreten ist), und Sie die falschen Zeichen durch die richtigen Zeichen ersetzen möchten (siehe auch str.translate()https://docs.python.org/3.4/library/stdtypes.html?highlight=translate#str.translate).

Möglicherweise verwendete das ODBC intern die falsche Codierung. (Das ist der Inhalt der Datenbank möglicherweise korrekt, aber es wurde von der ODBC falsch interpretiert, und Sie können der ODBC nicht sagen, was die richtige Codierung ist.) Dann möchten Sie die Zeichenfolge zurück in Bytes mit dem falsch codieren Kodierung, und dann decodieren Sie die Bytes mit der rechts Kodierung.

+0

Ich benutze Visuafoxpro Driver, um auf eine xbase .dbf-Tabelle zuzugreifen. Der Zeichensatz scheint cp1252 mit allen Sonderzeichen in ASCII zu sein. Ich habe viele verschiedene Codierungen ausprobiert, und ich habe die besten Ergebnisse mit diesen. Vielen Dank für Ihre Hilfe ! – Romu

+0

Ich weiß nicht, wie Sie dem VisualFoxPro-Treiber die Codierung mitteilen. War es anders als 'cp1252'? – pepr

+0

Gibt es eine Möglichkeit, String wie "b'hello '" zurück in Byte-Format zu konvertieren? Ich muss dies tun, da ich eine Datei mit Unicode-Daten als Zeichenfolgendarstellung habe, und um sie zu analysieren, müsste ich den Dateityp in Bytes umwandeln. Vielen Dank im Voraus. – skadoosh

Verwandte Themen