Ich möchte einen Fall behandeln, in dem ein Dateinamenfehler auftritt.
Selbst wenn der Dateiname auf Japanisch identisch ist, ist er völlig unterschiedlich, je nachdem, ob der Zeichencode utf-8 oder shift-jis ist. Dank der intelligenten Interpretation der Benutzeroberfläche, auf der der Dateiname angezeigt wird, können Sie normalerweise ohne Kopf arbeiten. Wenn Sie dies jedoch mit Python tun müssen, wird der Zeichencode gemischt (der Zeichencode unterscheidet sich je nach zu behandelnder Datei). Situation) wird sehr problematisch. Während ich diesmal die Anzeige und Konvertierung jedes Zeichencodes verstehe, möchte ich endlich den japanischen Dateinamen von shift-jis in utf-8 konvertieren, was die Standardeinstellung von python3 ist.
Die Annahme ist 3 Serien. ** 3 Serien ** (wichtig, da es sich um Zeichencode handelt). Die meisten Kenntnisse, die für den Zeichencode in diesem Artikel erforderlich sind, sind ** Offizielle Website ** (einschließlich Zitate) und einige Es wurde von ** dieser Site ** bezogen.
Ich habe das Bild von "Sind auf die Wunde legen" von [Irasutoya] heruntergeladen (https://www.irasutoya.com/2013/03/blog-post_1999.html). Dieser Name scheint je nach Region unterschiedlich zu sein (?). In diesem Artikel werden wir die Beziehung zwischen diesen Namen wie folgt behandeln.
Der Name "Bansokou" lautet [Daijirin](https://www.weblio.jp/content/%E3%81%B0%E3%82%93%E3%81%9D%E3%81%86% Es ist eine gebräuchliche Nomenklatur, die in E3% 81% 93% E3% 81% 86 veröffentlicht wurde, während "Cut Bang (Yutoku Yakuhin Kogyo Co., Ltd. 1.html)) ”und“ Band Aid (Johnson End Johnson Co., Ltd.) ”sind Produktnamen. Ich weiß, dass es je nach Vertriebsgesellschaft Unterschiede in Leistung und Material gibt (ich habe sie nicht verglichen), aber der Einfachheit halber sind in diesem Artikel alle diese Namen gleich: "Sollen auf die Wunde gelegt werden". Angenommen, es ist ein Hinweiswort __.
Mit anderen Worten, "derjenige, der an der Wunde befestigt werden soll" wird durch den eindeutigen <Name (Produktname) und Notation> gemäß den vier Arten von Verbalisierungsregeln (** Zeichencode **) in der Figur dargestellt. Das Anwenden dieser Verbalisierungsregel zum Übersetzen von
Eine Unicode-Zeichenfolge ist eine Zeichenfolge von Codepunkten, bei der es sich um eine Zahl von 0 bis 0x10FFFF handelt (1.114.111 in Dezimalschreibweise). Diese Codepunktzeichenfolge wird im Speicher als Codeeinheitsspalte dargestellt, die einer 8-Bit-Bytezeichenfolge zugeordnet ist. Die Regeln zum Übersetzen einer Unicode-Zeichenfolge als Byte-Zeichenfolge werden als Zeichencodierung oder einfach als Codierung bezeichnet. (Weggelassen) Die Standardcodierung des Python-Quellcodes ist UTF-8, sodass Sie Unicode-Zeichen unverändert in Zeichenfolgenliterale aufnehmen können.
Im Python-Code wird der Str-Typ "An der Wunde anbringen" mit der ** Unicode-Zeichenfolge ** (und dem entsprechenden ** Codepunkt **) ausgedrückt. Wenn dann eine Codierung für die Zeichenfolgenverarbeitung erforderlich ist, wird diese unter Verwendung des Standardzeichencodes (Hirakana im Beispiel UTF-8 in Python) als "Bansoko" codiert.
Der Standardzeichencode kann mit dem folgenden Code bestätigt werden.
Überprüfen Sie den Standardzeichencode
import sys
print(sys.getdefaultencoding()) # → utf-8
Umgekehrt wird die Anzeige des
Sie können auch die decode () -Methode der Klasse> bytes verwenden, um eine Zeichenfolge zu erstellen. Diese Methode verwendet einen UTF-8-ähnlichen Wert als Codierungsargument und optional ein Fehlerargument.
Da die Entsprechung zwischen
Sofort wird die Zeichenfolge "Akasatana" mit vier Arten von Zeichencodes codiert.
utf-8 und verschieben-Vergleich von jis
str_src = 'Akasa Tana'
enc_utf = str_src.encode() # default: encoding="utf-8"
enc_u16 = str_src.encode('utf-16')
enc_euc = str_src.encode('euc_jp')
enc_jis = str_src.encode('shift-jis')
print('--- ENCODE ---')
print('encoded by utf-8:', enc_utf, '(length={})'.format(len(enc_utf)))
print('encoded by utf-16:', enc_u16, '(length={})'.format(len(enc_u16)))
print('encoded by euc_jp:', enc_euc, '(length={})'.format(len(enc_euc)))
print('encoded by shift-jis:', enc_jis, '(length={})'.format(len(enc_jis)))
print('--- DECODE ---')
print(enc_utf.decode(), enc_u16.decode('utf-16'), enc_euc.decode('euc_jp'), enc_jis.decode('shift-jis'))
'''
--- ENCODE ---
encoded by utf-8: b'\xe3\x81\x82\xe3\x81\x8b\xe3\x81\x95\xe3\x81\x9f\xe3\x81\xaa' (length=15)
encoded by utf-16: b'\xff\xfeB0K0U0_0j0' (length=12)
encoded by euc_jp: b'\xa4\xa2\xa4\xab\xa4\xb5\xa4\xbf\xa4\xca' (length=10)
encoded by shift-jis: b'\x82\xa0\x82\xa9\x82\xb3\x82\xbd\x82\xc8' (length=10)
--- DECODE ---
Akasata Akasata Akasata Akasata
'''
Die Ausgabe wird wie folgt dargestellt (utf-16 wird auch in hexadezimaler Schreibweise angezeigt).
Die zwei Bytes, die zu Beginn der Codierung mit utf-16 angezeigt werden, sind ein Code namens BOM.
Das Unicode-Zeichen U + FEFF wird als Stücklistenreihenfolge (BOM) verwendet und als erstes Zeichen in die Datei geschrieben, um die automatische Bestimmung der Bytereihenfolge der Datei zu erleichtern. Einige Codierungen, wie z. B. UTF-16, erfordern eine Stückliste am Anfang der Datei. Wenn eine solche Codierung verwendet wird, wird die Stückliste automatisch als erstes Zeichen und beim Lesen der Datei geschrieben Wird implizit entfernt.
Erwägen Sie nun, eine Datei zu erstellen, indem Sie den Dateinamen im Python-Code angeben. Wie üblich denken wir über das Prinzip nach, indem wir es auf die Wunde kleben. Um es noch einmal zu wiederholen: ** Hier konzentrieren wir uns auf den "Dateinamen" und fahren mit der Diskussion fort, ohne uns über den Inhalt der erstellten Datei Gedanken zu machen **.
Bei der Herstellung von "An einer Wunde befestigen" wird der Name "Anruf" auf der Disc aufgezeichnet. Wenn dann "das" benötigt wird, wird es jedes Mal von "Berufung" zu "derjenige, der an der Wunde befestigt werden soll" im Gehirn der erwarteten Verbalisierungsregel übersetzt (dekodiert).
Betrachten Sie hier den Fall, in dem die erwartete Verbalisierungsregel nur die von Yutoku Yakuhin ist. Wenn das
Wenn Sie ohne nachzudenken arbeiten, wird der in Python3 standardmäßig angegebene Codierungszeichencode beim Generieren der Datei auf den Dateinamen angewendet. Darüber hinaus wird auch die Standardeinstellung des Arguments "Fehler" bestimmt. Diese können auch durch den folgenden Code bestätigt werden.
python
import sys
print(sys.getfilesystemencoding())
print(sys.getfilesystemencodeerrors())
'''
utf-8
surrogateescape
'''
"Surrogate" selbst wurde neu als Code eingeführt, um den Ausdrucksbereich von Unicode weiter zu erweitern. In "Errors = Surrogate Escape" zum Zeitpunkt der Decodierung des Bytetyps von Python3 wird der entsprechende Teil der Bytes, dessen Dekodierung nicht funktioniert, durch die in Surrogate verwendete Unicode-Zeichenfolge ersetzt. Obwohl die Decodierung selbst unvollständig ist, können Fehler vermieden werden, ohne dass die ursprünglichen Bytetypinformationen verloren gehen. Wenn Sie denselben Code neu codieren möchten, wird die durch Angabe von "Errors = Surrogate Escape" eingefügte Unicode-Zeichenfolge gelöscht, damit das ursprüngliche Formular wiederhergestellt werden kann.
Der Surrogateescape-Fehlerbehandler dekodiert alle Nicht-ASCII-Bytes als Codepunkte im privaten Unicode-Bereich von U + DC80 bis U + DCFF. Diese privaten Codepunkte werden bei Verwendung von Surrogateescape, einem Fehlerbehandler beim Codieren und Zurückschreiben der Daten, auf dieselben Bytes zurückgegeben.
Wenn Sie nun überlegen, die Datei mit dem japanischen Namen utf-8 und shift-jis zu speichern, beachten Sie die obigen Punkte.
Importieren Sie das zu verwendende Modul und erstellen Sie ein Arbeitsverzeichnis. In diesem Artikel werden keine Zeichencode-Verarbeitungsmodule wie Codecs verwendet (ich bin mir nicht sicher).
Vorbereitung: Importieren Sie das zu verwendende Modul und erstellen Sie ein Arbeitsverzeichnis
import os
import glob
testdir = './testdir'
if not os.path.exists(testdir):
os.mkdir(testdir)
#Suchen Sie den Pfad aus dem aktuellen Verzeichnis und zeigen Sie ihn an, wobei Sie sich auf das Verzeichnis beschränken
print([p for p in glob.glob('./*') if os.path.isdir(p)])
'''
[..., './testdir', ...]
'''
Wie oben erwähnt, wird der Zeichencode utf-8 als Standardwert von python3 angegeben, sodass Sie nicht vorsichtig sein müssen.
Erstellen Sie das utf-8-Verzeichnis "aiueo" im Arbeitsverzeichnis mit os.mkdir ()
.
Verzeichnis erstellen (utf-8)
utf_dirname = os.path.join(testdir, 'AIUEO')
os.mkdir(utf_dirname)
Erstellen Sie außerdem "Kakikukeko.txt" in "Aiueo". Obwohl in diesem Artikel nicht verwendet, wird die Zeichenfolge von utf-8 in der Datei ausgegeben.
Dateierstellung (utf-8)
utf_filename = os.path.join(utf_dirname, 'Kakikukeko.txt')
with open(utf_filename, 'w') as f:
f.write('SA Shi Su Se So.\n')
Erstellen Sie abschließend eine neue Datei, deren Dateiname durch shift-jis definiert ist.
Erstellen Sie ein Shift-Jis-Verzeichnis "Akasatana" im Arbeitsverzeichnis.
Bisher wurde der Typ str an os.mkdir ()
übergeben, aber er funktioniert normal, auch wenn der Typ ** Bytes eingefügt ist **.
python
jis_dirname = os.path.join(testdir, 'Akasa Tana').encode('shift-jis')
print(jis_dirname)
os.mkdir(jis_dirname)
'''
b'./testdir/\x82\xa0\x82\xa9\x82\xb3\x82\xbd\x82\xc8'
'''
Früher haben wir gezeigt, dass ein neues Verzeichnis mit dem Pfadnamen des Bytetyps erstellt werden kann, aber dieses Mal werden wir das Shift-Jis-Verzeichnis "Akasatana" mit dem Typ str erstellen. Wie oben erwähnt, ist bekannt, dass beim Codieren des Dateinamens standardmäßig "encoding =" utf-8 "und" error = "Surrogate Escape" verwendet werden. Verwenden Sie diese Optionen, um den Bytetyp in "str" zu ändern. Konvertieren (dekodieren) in. Durch Angabe von "error" wird "dc" am Anfang jeder Ausgabe-Unicode-Zeichenfolge hinzugefügt. Wenn die generierte Unicode-Zeichenfolge vom Typ str durch diese spezielle Decodierung in "print ()" eingefügt wird, wird ein Fehler ("UnicodeDecodeError") ausgelöst. Daher wird die Unicode-Zeichenfolge so ausgegeben, wie sie ist, indem sie in "repr ()" eingeschlossen wird.
Verzeichnis erstellen (verschieben-jis)
jis_dirname_bytes = os.path.join(testdir, 'Akasa Tana'.encode('shift-jis')
jis_dirname_str = jis_dirname_bytes.decode(errors='surrogateescape'))
print(repr(jis_dirname_str))
os.mkdir(jis_dirname_str)
'''
'./testdir/\udc82\udca0\udc82\udca9\udc82\udcb3\udc82\udcbd\udc82\udcc8'
'''
Erstellen Sie "Hamayarawa.txt" im Verzeichnis "Akasatana" mit shift-jis. Der Zeichencode des Textes in der Datei wird auch durch "encoding =" shift-jis "auf shift-jis gesetzt.
Dateierstellung (Shift-jis)
jis_filename = os.path.join(jis_dirname, 'Hamayarawa.txt'.encode('shift-jis'))
# encode()Nach.decode(errors='surrogateescape')Kann beigefügt werden
with open(jis_filename, 'w', encoding='shift-jis') as f:
f.write('Plötzlich\n Himiri')
Bisher haben wir den Dateinamen mit zwei Arten von Zeichencodes definiert, aber lassen Sie uns ihn mit der Benutzeroberfläche und glob.glob ()
anzeigen. In der folgenden Abbildung ist das blaue Quadrat in der Mitte der Name der gespeicherten Datei (Bytes). Die untere Seite zeigt das Ergebnis der Benutzeroberfläche, die den Dateinamen durch Angabe des Zeichencodes übersetzt, und die obere Seite zeigt das Ergebnis der Erfassung der Dateinamenliste in str-Typ oder des Bytetyps in Python.
Ich habe die obere Seite von Jupyter Notebook verwendet. Obwohl das von utf-8 erstellte Verzeichnis "aiueo" normal angezeigt wird. Das von shift-jis erstellte "Akasatana" -Verzeichnis ist verstümmelt und kann nicht ausgewählt werden.
"Kakikukeko.txt" im Verzeichnis "Aiueo" wird ebenfalls problemlos angezeigt.
Ich habe WinSCP verwendet. Obwohl das von shift-jis erstellte Verzeichnis "Akasatana" normal angezeigt wird. Das von utf-8 erstellte "aiueo" -Verzeichnis ist verstümmelt, und bei Auswahl tritt ein Fehler auf.
"Hamayarawa.txt" im Verzeichnis "Akasatana" wird ebenfalls problemlos angezeigt.
glob.glob ()
Wenn Sie versuchen, eine Liste der Dateien im Arbeitsverzeichnis normal abzurufen, wird der Dateiname vom Standard-utf-8 dekodiert, sodass das Verzeichnis ** "Akasatana" ein str-Typ mit "Ersatz-Escape" ** ist.
utf-Pfadnamenanzeige mit 8
print(glob.glob(os.path.join(testdir, '*')))
print(glob.glob(os.path.join(testdir, 'AIUEO', '*')))
'''
['./testdir/AIUEO',
'./testdir/\udc82\udca0\udc82\udca9\udc82\udcb3\udc82\udcbd\udc82\udcc8']
['./testdir/AIUEO/Kakikukeko.txt']
'''
Hier wird der Bytetyp ** glob.glob ()
zugewiesen, und der Dateiname wird durch die ** Methode zum Decodieren der erhaltenen Ausgabe mit einem beliebigen Code erfasst.
Wenn Sie mit shift-jis dekodieren, wird der Name des Verzeichnisses "Akasatana" normal angezeigt und das Verzeichnis "Aiueo" wird verstümmelt.
Liste der Pfadnamen mit Bytes
#Dateinamen mit Bytetyp abrufen
bytes_paths = glob.glob(os.path.join(testdir, '*').encode())
print(bytes_paths)
# utf-Bei 8 dekodieren
print([f.decode(errors='surrogateescape') for f in bytes_paths])
# shift-Mit jis dekodieren
print([f.decode('shift-jis', errors='surrogateescape') for f in bytes_paths])
'''
[b'./testdir/\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a',
b'./testdir/\x82\xa0\x82\xa9\x82\xb3\x82\xbd\x82\xc8']
['./testdir/AIUEO',
'./testdir/\udc82\udca0\udc82\udca9\udc82\udcb3\udc82\udcbd\udc82\udcc8']
['./testdir/縺 > 縺\udc86 Doktor ♀',
'./testdir/Akasa Tana']
'''
Ändern Sie abschließend den von shift-jis gespeicherten Dateinamen in den von utf-8 definierten Dateinamen.
Holen Sie sich den Pfad des von shift-jis definierten Verzeichnisses direkt und ersetzen Sie ihn durch die Zeichenfolge von utf-8 durch os.rename ()
.
Konvertierung von Zeichencode für einzelne Verzeichnisse
target = glob.glob(os.path.join(testdir, '*').encode())[1]
print(repr(target))
print(target.decode('shift-jis'))
os.rename(target, target.decode('shift-jis'))
'''
b'./testdir/\x82\xa0\x82\xa9\x82\xb3\x82\xbd\x82\xc8'
./testdir/Akasa Tana
'''
Das Ergebnis ist unten dargestellt. Der Zeichencode wurde erfolgreich konvertiert und "Akasatana" ist zu sehen.
Geben Sie das Verzeichnis "Akasatana" ein.
In diesem Artikel gibt es nur eine Datei. Unter der Annahme, dass eine Zeichencodekonvertierung mehrerer Dateien erforderlich ist, haben wir dem Code mit hinzugefügter Schleifenverarbeitung entsprochen. Der "Akasatana" -Teil konzentriert sich auf den japanischen Teil und ist die utf-8-Zeichenkette. Die "Hamayarawa.txt" ist die Shift-jis-Zeichenkette Gibt einen Fehler zurück ** (Da der Teil "./testdir" in der ASCII-Zeichenfolge enthalten ist, arbeiten sowohl utf-8 als auch shift-jis mit gemeinsamen Bytes, sodass Sie nicht darüber nachdenken müssen.) Diese beiden müssen vor der Verarbeitung getrennt werden.
Zeichencode-Konvertierung aller Dateien im Verzeichnis
for f in glob.glob(os.path.join(testdir, 'Akasa Tana', '*').encode()):
#Verzeichnisname (utf-Mit 8 dekodieren)
d_str = os.path.dirname(f).decode()
#Dateiname (Verschiebung-Mit jis dekodieren)
b_str = os.path.basename(f).decode('shift-jis')
#Zeichencode-Konvertierung
os.rename(f, os.path.join(d_str, b_str))
Damit wurde auch "Hamayarawa.txt" sicher mit dem Zeichencode von utf-8 definiert.
Wenn ich bis zu diesem Punkt zusammenfasse, denke ich, dass ich endlich die Tipps zum Manipulieren von Zeichenketten verstanden habe. Insbesondere stellte ich fest, dass die Arbeit viel einfacher wird, wenn ich den Bytetyp gut benutze, an den ich gewöhnt war und den ich überhaupt nicht interessierte. Wenn Sie zum Zeitpunkt der Codierung / Decodierung die Behandlung von "Fehlern" auswählen können, können Sie den größten Teil der Arbeit erledigen.
Schließlich finde ich, dass das offizielle Dokument am einfachsten zu verstehen ist.