Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Einführung in die Python-Zeichenkodierung

Detaillierte Einführung in die Python-Zeichenkodierung

高洛峰
高洛峰Original
2017-03-28 17:19:581386Durchsuche

1. ZeichenkodierungEinführung

1.1. ASCII

ASCII (American Standard Code for Information Interchange) ist eine Einzelbyte-Kodierung. Zu Beginn gab es in der Computerwelt nur Englisch, und ein einzelnes Byte kann 256 verschiedene Zeichen darstellen Alle englischen Zeichen und viele Steuersymbole, aber ASCII verwendet nur die Hälfte davon (unterhalb von x80), was auch die Grundlage für die Realisierung von MBCS darstellt

In der Computerwelt gab es jedoch bald ​​der Welt, und Einzelbyte-ASCII konnte den Bedarf nicht mehr decken. Später entwickelte jede Sprache ihre eigene Kodierung, da es zu wenige Zeichen gab, die durch ein einzelnes Byte dargestellt werden konnten, und sie außerdem mit ASCII kompatibel sein musste Daher verwenden diese Codierungen Multibytes zur Darstellung von Zeichen, z. B. GBxxx, BIGxxx usw. Ihre Regel lautet: Wenn das erste Byte unter x80 liegt, stellt es immer noch ASCII-Zeichen dar. Wenn es über x80 liegt, folgt es Das nächste Byte zusammen (insgesamt zwei Bytes) stellt ein Zeichen dar, überspringt dann das nächste Byte und fährt mit der Beurteilung fort.

Hier hat IBM ein Konzept namens Codepage erfunden, um diese zu codieren GBK ist die Seite 936, also CP936. Der allgemeine Name lautet daher „GBK“. Daher wird es manchmal als DBCS (Double-Byte Character Set) bezeichnet. Es muss klar sein, dass es sich bei MBCS nicht um eine bestimmte Kodierung handelt Die Kodierung in

Linux

In Windows können Sie die Zeichen MBCS nicht sehen, da Microsoft ANSI verwendet, um fremder zu sein. Die Kodierung ANSI im Dialogfeld „Speichern unter“ von Notepad ist Gleichzeitig bezieht es sich in der Standard-Gebietsschemaeinstellung von Windows auf GBK.

Später hatte ich das Gefühl, dass zu viele Codes die Welt zu komplex gemacht hatten und mir Kopfschmerzen bereiteten Wir saßen alle zusammen und überlegten uns eine Methode: Zeichen in allen Sprachen sollten durch denselben Zeichensatz dargestellt werden. Das ist Unicode Der ursprüngliche Unicode-Standard UCS. 2 verwendet zwei Bytes zur Darstellung eines Zeichens, daher hört man oft, dass Unicode zwei Bytes zur Darstellung eines Zeichens verwendet. Aber bald darauf waren einige Leute der Meinung, dass 256*256 zu wenig sei und immer noch nicht ausreiche, und so erschien der UCS-4-Standard, der 4 Bytes zur Darstellung eines Zeichens verwendet, aber der von uns am häufigsten verwendete ist immer noch UCS-2 .

UCS (Unicode Character Set) ist nur eine Tabelle von Codepunkten, die Zeichen entsprechen. Der Codepunkt des Wortes „汉“ ist beispielsweise 6C49. UTF (UCS Transformation Format) ist für die spezifische Übertragung und Speicherung von Zeichen verantwortlich.

Das ist zunächst sehr einfach, verwenden Sie einfach den UCS-Codepunkt zum direkten Speichern, also UTF-16. Beispielsweise kann „Han“ direkt mit x6Cx49 (UTF-16-BE) gespeichert werden umgekehrt. x49x6C speichern (UTF-16-LE). Aber nachdem sie es verwendet haben, haben die Amerikaner das Gefühl, dass sie einen großen Verlust erlitten haben. Früher brauchten englische Buchstaben nur ein Byte zum Speichern, aber jetzt sind es zwei Bytes, nachdem sie einen großen Topf gegessen haben, und der Platzverbrauch hat sich verdoppelt ... Also UTF-8 Aus dem Nichts. UTF-8 ist eine sehr umständliche Kodierung. Insbesondere ist es eine variable Länge und kompatibel mit ASCII-Zeichen, die durch 1 Byte dargestellt werden. Was hier weggelassen wird, muss jedoch an anderer Stelle extrahiert werden. Sie haben sicher gehört, dass chinesische Zeichen in UTF-8 zum Speichern 3 Bytes benötigen, oder? Die in 4 Bytes gespeicherten Zeichen sind noch tränenreicher ... (Bitte suchen Sie nach Details darüber, wie UCS-2 zu UTF-8 wurde)

Eine weitere erwähnenswerte Sache ist BOM (Byte Order Mark). Wenn wir die Datei speichern, wird die in der Datei verwendete Codierung nicht gespeichert. Beim Öffnen müssen wir uns die beim Speichern verwendete Codierung merken und sie mit dieser Codierung öffnen. (Vielleicht möchten Sie sagen, dass Notepad es Ihnen nicht erlaubt, beim Öffnen der Datei die Kodierung auszuwählen? Sie können genauso gut zuerst Notepad öffnen und dann Datei-> Öffnen verwenden, um sie anzuzeigen.) UTF führt BOM ein, um seine eigene Kodierung darzustellen eine davon, was bedeutet, dass die für den als nächstes zu lesenden Text verwendete Kodierung die entsprechende Kodierung ist:

BOM_UTF8 'xefxbbxbf'

BOM_UTF16_LE 'xffxfe'

BOM_UTF16_BE 'xfexff'

Nicht alle

Editoren

schreiben BOM, aber auch ohne BOM kann Unicode weiterhin gelesen werden, aber wie bei der MBCS-Kodierung muss die spezifische Kodierung separat angegeben werden, da sonst die Dekodierung fehlschlägt.

Sie haben vielleicht gehört, dass UTF-8 kein BOM erfordert. Das stimmt nicht, aber die meisten Editoren lesen UTF-8 als Standardkodierung, wenn kein BOM vorhanden ist. Sogar Notepad, das beim Speichern standardmäßig ANSI (MBCS) verwendet, verwendet zuerst die UTF-8-Testkodierung, wenn die Datei liest. Wenn sie erfolgreich dekodiert werden kann, wird UTF-8 zum Dekodieren verwendet. Dieser umständliche Ansatz von Notepad hat einen Fehler verursacht: Wenn Sie eine neue Textdatei erstellen, „姹姧“ eingeben und sie dann mit ANSI (MBCS) speichern, wird sie beim erneuten Öffnen zu „Han a“. Probieren Sie es aus:)

2. Kodierungsprobleme in Python

2.1. str und Unicode

Str und Unicode sind beide Unterklassen von Basestring . Genau genommen handelt es sich bei str tatsächlich um eine Bytefolge, bei der es sich um eine Folge von Unicode-codierten Bytes handelt. Bei Verwendung der Funktion len()

für den UTF-8-codierten String „汉“ ist das Ergebnis 3, da tatsächlich UTF-8-codierter „汉“ == „xE6xB1x89“ ist.

Unicode ist die echte

Zeichenfolge, die durch Dekodierung der Bytezeichenfolge str mit der richtigen Zeichenkodierung und len(u'汉') == 1 erhalten wird.

Werfen wir einen Blick auf die beiden Basisstring-Instanzmethoden encode() und decode() Nachdem wir den Unterschied zwischen str und unicode verstanden haben, werden diese beiden Methoden nicht mehr verwechselt:

# coding: UTF-8
 
u = u'汉'
print repr(u) # u'\u6c49'
s = u.encode('UTF-8')
print repr(s) # '\xe6\xb1\x89'
u2 = s.decode('UTF-8')
print repr(u2) # u'\u6c49'
 
# 对unicode进行解码是错误的
# s2 = u.decode('UTF-8')
# 同样,对str进行编码也是错误的
# u2 = s.encode('UTF-8')
Es ist zu beachten, dass es zwar falsch ist, die Methode encode() für str aufzurufen, Python jedoch keine

Ausnahme auslöst, sondern einen anderen str mit demselben Inhalt, aber einer anderen ID für zurückgibt Unicode Das Gleiche gilt für den Aufruf der decode()-Methode. Ich verstehe wirklich nicht, warum encode() und decode() nicht in unicode bzw. str, sondern beide in basestring platziert werden. Da dies jedoch der Fall ist, sollten wir vorsichtig sein, um Fehler zu vermeiden.

2.2. Zeichenkodierungsdeklaration

Wenn in der Quellcodedatei Nicht-ASCII-Zeichen verwendet werden, muss im Header der Datei eine Zeichenkodierungsdeklaration wie folgt vorgenommen werden:

#-*- coding: UTF-8 -*-
Tatsächlich überprüft Python nur #, Codierung und Codierungszeichenfolge, andere Zeichen werden für das Erscheinungsbild hinzugefügt. Darüber hinaus gibt es in Python viele Zeichenkodierungen und viele Aliase, bei denen die Groß-/Kleinschreibung nicht beachtet wird. UTF-8 kann beispielsweise als u8 geschrieben werden. Siehe http://docs.python.org/library/codecs.html#standard-encodings.

Außerdem ist zu beachten, dass die deklarierte Codierung mit der Codierung übereinstimmen muss, die beim tatsächlichen Speichern der Datei verwendet wurde. Andernfalls besteht eine hohe Wahrscheinlichkeit, dass Ausnahmen bei der Codeanalyse auftreten. Heutige IDEs bewältigen diese Situation im Allgemeinen automatisch. Nach dem Ändern der Deklaration wird sie in der deklarierten Codierung gespeichert, aber bei der Steuerung des Texteditors muss man vorsichtig sein:)

Dateien lesen und schreiben

Eingebaut Wenn die open()-Methode eine Datei öffnet, liest read() str. Nach dem Lesen müssen Sie zum Dekodieren() das richtige Codierungsformat verwenden. Wenn es sich beim Schreiben von () um einen Unicode-Parameter handelt, müssen Sie die Codierung verwenden, die Sie in encode() schreiben möchten. Wenn es sich in anderen Codierungsformaten um einen str handelt, müssen Sie zuerst die Codierung des str verwenden, um ihn zu decodieren() und konvertieren Sie es in Unicode. Verwenden Sie dann die geschriebene Codierung für encode(). Wenn Sie Unicode direkt als Parameter an die write()-Methode übergeben, kodiert Python zunächst mit der in der Quellcodedatei deklarierten Zeichenkodierung und schreibt dann.

# coding: UTF-8
 
f = open('test.txt')
s = f.read()
f.close()
print type(s) # <type &#39;str&#39;>
# 已知是GBK编码,解码成unicode
u = s.decode('GBK')
 
f = open('test.txt', 'w')
# 编码成UTF-8编码的str
s = u.encode('UTF-8')
f.write(s)
f.close()
Darüber hinaus stellen die Modulcodecs eine open()-Methode bereit, die eine Codierung zum Öffnen der Datei angeben kann. Die mit dieser Methode geöffnete Datei liest und gibt Unicode zurück. Wenn der Parameter beim Schreiben Unicode ist, wird er mit der während open() angegebenen Codierung codiert. Wenn er dann str ist, wird er gemäß der in der Quellcodedatei deklarierten Zeichencodierung in Unicode decodiert, bevor der Parameter ausgeführt wird oben genannten Vorgang. Im Vergleich zum integrierten open() ist diese Methode weniger anfällig für Codierungsprobleme.

# coding: GBK
 
import codecs
 
f = codecs.open('test.txt', encoding='UTF-8')
u = f.read()
f.close()
print type(u) # <type &#39;unicode&#39;>
 
f = codecs.open('test.txt', 'a', encoding='UTF-8')
# 写入unicode
f.write(u)
 
# 写入str,自动进行解码编码操作
# GBK编码的str
s = '汉'
print repr(s) # '\xba\xba'
# 这里会先将GBK编码的str解码为unicode再编码为UTF-8写入
f.write(s)
f.close()
2.4. Kodierungsbezogene Methoden

Das Modul sys/locale bietet einige Methoden zum Abrufen der Standardkodierung in der aktuellen Umgebung.

# coding:gbk
 
import sys
import locale
 
def p(f):
    print '%s.%s(): %s' % (f.module, f.name, f())
 
# 返回当前系统所使用的默认字符编码
p(sys.getdefaultencoding)
 
# 返回用于转换Unicode文件名至系统文件名所使用的编码
p(sys.getfilesystemencoding)
 
# 获取默认的区域设置并返回元祖(语言, 编码)
p(locale.getdefaultlocale)
 
# 返回用户设定的文本数据编码
# 文档提到this function only returns a guess
p(locale.getpreferredencoding)
 
# \xba\xba是'汉'的GBK编码
# mbcs是不推荐使用的编码,这里仅作测试表明为什么不应该用
print r"'\xba\xba'.decode('mbcs'):", repr('\xba\xba'.decode('mbcs'))
 
#在笔者的Windows上的结果(区域设置为中文(简体, 中国))
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp936')
#locale.getpreferredencoding(): cp936
#'\xba\xba'.decode('mbcs'): u'\u6c49'
3. Einige Vorschläge

3.1 Verwenden Sie die Zeichenkodierungsdeklaration, und alle Quellcodedateien im selben Projekt verwenden dieselbe Zeichenkodierungsdeklaration.

Dies muss getan werden.

3.2. Geben Sie str auf und verwenden Sie Unicode für alle.

Drücken Sie u, bevor Sie das Anführungszeichen drücken. Am Anfang ist es wirklich schwer, sich daran zu gewöhnen, und man vergisst oft, zurückzugehen und das Problem zu beheben, aber wenn man das tut, kann man 90 % davon reduzieren Codierungsprobleme. Wenn das Codierungsproblem nicht schwerwiegend ist, müssen Sie diesen Artikel nicht lesen.

3.3. Verwenden Sie codecs.open() anstelle des integrierten open().

Wenn das Codierungsproblem nicht schwerwiegend ist, müssen Sie diesen Artikel nicht lesen.

3.4. Zeichenkodierungen, die unbedingt vermieden werden müssen: MBCS/DBCS und UTF-16.

Das hier erwähnte MBCS bedeutet nicht, dass GBK oder irgendetwas anderes nicht verwendet werden kann, sondern dass Sie die Codierung namens „MBCS“ in Python nicht verwenden sollten, es sei denn, das Programm ist überhaupt nicht portierbar.

Die Kodierung „MBCS“ und „DBCS“ in Python sind Synonyme und beziehen sich auf die Kodierung, auf die sich MBCS in der aktuellen

Windows-Umgebung bezieht. In der Linux-Implementierung von Python gibt es keine solche Codierung, daher wird es nach der Portierung auf Linux definitiv zu Ausnahmen kommen! Solange die Windows-Systemregion unterschiedlich ist, ist außerdem auch die von MBCS genannte Codierung unterschiedlich. Das Ergebnis der Festlegung verschiedener Bereiche und der Ausführung des Codes in Abschnitt 2.4:

#中文(简体, 中国)
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp936')
#locale.getpreferredencoding(): cp936
#'\xba\xba'.decode('mbcs'): u'\u6c49'
 
#英语(美国)
#sys.getdefaultencoding(): UTF-8
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp1252')
#locale.getpreferredencoding(): cp1252
#'\xba\xba'.decode('mbcs'): u'\xba\xba'
 
#德语(德国)
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp1252')
#locale.getpreferredencoding(): cp1252
#'\xba\xba'.decode('mbcs'): u'\xba\xba'
 
#日语(日本)
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp932')
#locale.getpreferredencoding(): cp932
#'\xba\xba'.decode('mbcs'): u'\uff7a\uff7a'

可见,更改区域后,使用mbcs解码得到了不正确的结果,所以,当我们需要使用'GBK'时,应该直接写'GBK',不要写成'MBCS'。

UTF-16同理,虽然绝大多数操作系统中'UTF-16'是'UTF-16-LE'的同义词,但直接写'UTF-16-LE'只是多写3个字符而已,而万一某个操作系统中'UTF-16'变成了'UTF-16-BE'的同义词,就会有错误的结果。实际上,UTF-16用的相当少,但用到的时候还是需要注意。

Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in die Python-Zeichenkodierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn