Dinge, die Sie bei der Verarbeitung von Zeichenfolgen in Python 3 beachten sollten

In Fortsetzung des Artikels Gestern werde ich diesmal meine eigene Richtlinie beim Umgang mit Zeichenketten in Python3 zusammenfassen.

Persönliches Fazit

Das ist nicht gut oder schlecht, es gibt nur nicht viele Fälle, in denen Sie sich mit Bytes in Ihrem Code befassen müssen.

Byte- und Zeichenkette

Die Byte-Zeichenfolge wird durch eine bestimmte Codierungsmethode codiert und im Literal als "b'a" ausgedrückt. Andererseits ist eine Zeichenfolge ein Array von Unicode-Codepunkten und wird in Literalen als "a" ausgedrückt.

Ich habe es kurz geschrieben, aber an dieser Stelle können Sie den Unterschied im Umgang mit Python 2 erkennen.

python


(py3.4)~ » ipython
   (Kürzung)
>>> b'a' #Byte-String
Out[1]: b'a'

#Die Literalschreibweise kann nicht verwendet werden, wenn Nicht-ASCII-Zeichen enthalten sind
#Die Zeichenfolge muss mit einer bestimmten Codierungsmethode codiert werden
>>> b'Ah' 
  File "<ipython-input-2-c12eb8e58bcd>", line 1
    b'Ah'
        ^
SyntaxError: bytes can only contain ASCII literal characters.

>>> 'Ah'.encode('utf-8') #String->Byte-String(Kodieren)
Out[3]: b'\xe3\x81\x82'


>>> 'Ah' #String
Out[4]: 'Ah'

>>> b'\xe3\x81\x82'.decode('utf-8') #Byte-String->String(Dekodieren)
Out[5]: 'Ah'


# Python2(Erneut veröffentlichen)
(py2.7)~ » ipython
   (Kürzung)
>>> 'Ah' #Byte-String
Out[1]: '\xe3\x81\x82'

>>> u'Ah' #Unicode-Zeichenfolge
Out[2]: u'\u3042'

>>> 'Ah'.decode('utf-8') (or unicode('Ah', 'utf-8')) #Byte-String->Unicode-Zeichenfolge(=Dekodieren)
Out[3]: u'\u3042'

>>> u'Ah'.encode('utf-8') #Unicode-Zeichenfolge->Byte-String(=Kodieren)
Out[4]: '\xe3\x81\x82'

Wenn Sie mit der Funktion "Typ" prüfen, können Sie feststellen, dass die Byte-Zeichenfolge vom Typ "Bytes" / die Zeichenfolge vom Typ "Str" ist.

python


>>> type(b'a')
Out[6]: bytes #≒ Python2-Str-Typ

>>> type('a')
Out[7]: str #≒ Python2-Unicode-Typ

Wie oben erwähnt, sind Python3-Byte-Zeichenfolgen keine "Zeichenfolgen". Daher kann es nicht mit einer Zeichenfolge verkettet werden, und die unterstützten Methoden unterscheiden sich. Dieser Punkt ist relativ wichtig, da es sich um dieselbe Zeichenfolge wie in Python2 handelt, die Verarbeitung irgendwie fortschreitet und schließlich "UnicodeEncodeError is ga", in Python3 jedoch "Fehler aufgrund unterschiedlichen Typs" und Fehlerausgabe / Der Ort des Auftretens ist relativ leicht zu verstehen.

python


>>> s = 'str' #String

>>> b = b'byte' #Byte-String

>>> s + b #String+Byte-String ist ein Fehler
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-20-5fe2240a1b50> in <module>()
----> 1 s + b

TypeError: Can't convert 'bytes' object to str implicitly

>>> s.find('t') #Die Zeichenfolge unterstützt die Suchmethode
Out[11]: 1

>>> b.find('y') #Die Byte-Zeichenfolge unterstützt die Suchmethode nicht.
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-24-e1b070a5aaba> in <module>()
----> 1 b.find('y')

TypeError: Type str doesn't support the buffer API

Ab Python 3.2 scheint es auch dann die geeignete Codierungsmethode aus dem Wert des Gebietsschemas auszuwählen, wenn die Standardausgabe mit einem anderen als dem Terminal verbunden ist. Daher funktionieren in Python2 die folgenden Fälle mit UnicodeEncodeError ebenfalls normal.

(Ref.) http://methane.hatenablog.jp/entry/20120806/1344269400 Nachtrag

python


(py3.4)~ » cat test.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

print('Ah' + 'Sagen')


#Im Terminal ausführen(Der Standardeingang / -ausgang ist mit dem Terminal verbunden)
(py3.4)~ » python test.py
Ah

#In Datei umleiten(Der Standardeingang / -ausgang ist nicht mit dem Terminal verbunden)
(py3.4)~ » python test.py > test.txt
(py3.4)~ » cat test.txt
Ah

UnicodeEncodeError ist nicht mehr beängstigend

Auch wenn Sie Ihren Tod nicht offenkundig melden, können Sie dennoch auf einen UnicodeEncodeError stoßen. Wenn Sie beispielsweise von cron aus ausführen, können Sie die Codierungsmethode nicht aus dem Gebietsschema auswählen und versuchen, mit ASCII zu codieren / decodieren, und Sie erhalten normalerweise UnicodeEncodeError.

(ref.) http://www.python.jp/pipermail/python-ml-jp/2014-November/011311.html (Die Veröffentlichung erfolgt äußerst zeitnah)

In Anbetracht dieser Dinge ist es möglicherweise besser, die Codierungsmethode immer mit der Umgebungsvariablen "PYTHONIOENCODING" anzugeben, ohne sich auf das Gebietsschema zu verlassen.

(ref.) http://methane.hatenablog.jp/entry/20120806/1344269400 (ref.) http://www.python.jp/pipermail/python-ml-jp/2014-November/011314.html

Was tun beim Umgang mit Bytes?

Sie können sys.stdin.buffer (Standardeingabe) / sys.stdout.buffer (Standardeingabe) verwenden, um Byte-Strings anstelle von Strings zu verarbeiten.

python


(py3.4)~ » cat test.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys

#print('Ah' + 'Sagen') #Druck ist sys.Schreiben Sie an stdout
sys.stdout.write('Ah' + 'Sagen' + '\n') # sys.Schreiben Sie eine Zeichenfolge in stdout
sys.stdout.buffer.write(('Ah' + 'Sagen' + '\n').encode('utf-8')) # sys.stdout.Schreiben Sie eine Zeichenfolge von Bytes zum Puffern

#Im Terminal ausführen
(py3.4)~ » python test.py
Ah
Ah

#In Datei umleiten
(py3.4)~ » python test.py > test.txt
(py3.4)~ » cat test.txt
Ah
Ah

Auch in Python 3 sind Bytes und Strings völlig unterschiedlich. Daher kann die Bytezeichenfolge nicht in "sys.stdout" geschrieben werden, das die Zeichenfolge schreibt, und die Zeichenfolge kann nicht in "sys.stdout.buffer" geschrieben werden, in das die Bytezeichenfolge geschrieben wird.

python


>>> import sys

#Textstrom(ref. https://docs.python.org/3/library/io.html#io.TextIOWrapper)
>>> type(sys.stdout) 
Out[2]: _io.TextIOWrapper

#Byte-Stream(ref. https://docs.python.org/3/library/io.html#io.BufferedWriter)
>>> type(sys.stdout.buffer)
Out[3]: _io.BufferedWriter 

#Bytes können nicht in den Textstrom geschrieben werden
>>> sys.stdout.write('a'.encode('utf-8')) 
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-581ae8b6af82> in <module>()
----> 1 sys.stdout.write('a'.encode('utf-8'))

TypeError: must be str, not bytes

#Strings können nicht in bytestream geschrieben werden
>>> sys.stdout.buffer.write('a') 
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-42da1d141b96> in <module>()
----> 1 sys.stdout.buffer.write('a')

TypeError: 'str' does not support the buffer interface

Recommended Posts

Dinge, die Sie bei der Verarbeitung von Zeichenfolgen in Python2 beachten sollten
Dinge, die Sie bei der Verarbeitung von Zeichenfolgen in Python 3 beachten sollten
Dinge, die Sie bei der Entwicklung von Crawlern in Python beachten sollten
Dinge, die Sie beim Kopieren von Python-Listen beachten sollten
Vorsichtsmaßnahmen bei der Verwendung von Python mit AtCoder
Dinge, die Sie bei der Verwendung von CGI mit Python beachten sollten.
Dinge, die Sie bei der Verwendung von Python beachten sollten, wenn Sie MATLAB verwenden
Beachten Sie Folgendes, wenn Sie automatisierte Tools für die Werkstatt in Python erstellen
Beachten Sie Folgendes, wenn Sie Keras auf Ihrem Mac bereitstellen
Beachten Sie Folgendes, wenn Sie mit ndarray einen Zeilenvektor in einen Spaltenvektor konvertieren
Beachten Sie beim Initialisieren einer Liste in Python
Dinge, auf die Sie achten müssen, wenn Sie Standardargumente in Python verwenden
3 Möglichkeiten, Zeitzeichenfolgen mit Python zu analysieren [Hinweis]
Eine clevere Möglichkeit zur Zeitverarbeitung mit Python
Fehler beim Versuch, psycopg2 in Python zu installieren
Dateiverarbeitung in Python
Multithread-Verarbeitung in Python
Verarbeitung in Python beenden
Vergleichen Sie Zeichenfolgen in Python
Strings in Python umkehren
Verwendung mehrerer Argumente bei der Parallelverarbeitung mithilfe der Mehrfachverarbeitung in Python
So messen Sie die Verarbeitungszeit mit Python oder Java
Ich möchte am Ende etwas mit Python machen
Ich möchte Strings in Kotlin wie Python manipulieren!
UTF8-Textverarbeitung mit Python
So löschen Sie stdout in Python
Asynchrone Verarbeitung (Threading) in Python
Achtung bei os.mkdir in Python
Sprechen mit Python [Text zu Sprache]
Bildverarbeitungssammlung in Python
Wie man in Python entwickelt
Verwenden des Python-Modus in der Verarbeitung
Post an Slack in Python
Python3-Verarbeitung, die in Paiza verwendbar zu sein scheint
Wovon ich süchtig war, als der Processing-Benutzer zu Python wechselte
Praktische Schreibmethode beim kontinuierlichen Anhängen an die Liste in Python
Was tun, wenn in Python "SSL: CERTIFICATE_VERIFY_FAILED _ssl.c: 1056" angezeigt wird?
Erlauben Sie Python, die Zeichenfolge der Eingabedatei aus dem Ordner auszuwählen
Verarbeitungsreihenfolge beim Verketten im PySpark
[Unterprozess] Wenn Sie ein anderes Python-Programm in Python-Code ausführen möchten
Überlassen Sie die mühsame Verarbeitung Python
[Python] Wie man PCA mit Python macht
Verarbeitung zur Verwendung von notMNIST-Daten in Python (und versucht, sie zu klassifizieren)
Vorsichtsmaßnahmen bei der Verwendung von Pit mit Python
Konvertieren Sie Markdown in Python in PDF
So sammeln Sie Bilder in Python
100 Sprachverarbeitung Knock Kapitel 1 in Python
Verhalten beim Auflisten in Python heapq
[Einführung in Python3 Tag 13] Kapitel 7 Zeichenfolgen (7.1-7.1.1.1)
Vorsichtsmaßnahmen beim Ausführen von Python unter EC2 über AWS Lambda (Befehl ausführen)
Im Python-Befehl zeigt Python auf Python3.8
[Einführung in Python3 Tag 14] Kapitel 7 Zeichenfolgen (7.1.1.1 bis 7.1.1.4)
Zeitzonenspezifikation beim Konvertieren einer Zeichenfolge in einen Datums- / Uhrzeittyp mit Python
[Python] Wenn Sie alle Variablen in einer anderen Datei verwenden möchten
Versuchen Sie, Trace in Python zu berechnen
[Einführung in Python3 Tag 15] Kapitel 7 Zeichenfolgen (7.1.2-7.1.2.2)
Wie man MySQL mit Python benutzt
So verpacken Sie C in Python
Verwendung von ChemSpider in Python
Verwendung von PubChem mit Python