Points à garder à l'esprit lors du traitement des chaînes en Python 3

Poursuivant l'article Hier, cette fois, je vais résumer ma propre politique concernant les chaînes de caractères en Python3.

Conclusion personnelle

Ce n'est ni bon ni mauvais, c'est juste qu'il n'y a pas beaucoup de cas où votre code doit actuellement traiter des octets.

Chaîne d'octets et chaîne de caractères

La chaîne d'octets est codée par une méthode de codage spécifique, et est exprimée par «b'a» dans le littéral. D'autre part, une chaîne de caractères est un tableau de points de code Unicode, et est exprimée par `` a '' en littéraux.

Je l'ai écrit brièvement, mais à ce stade, vous pouvez voir la différence de manipulation avec Python 2.

python


(py3.4)~ » ipython
   (réduction)
>>> b'a' #Chaîne d'octets
Out[1]: b'a'

#La notation littérale ne peut pas être utilisée lorsqu'elle contient des caractères non ASCII
#La chaîne doit être encodée avec une méthode d'encodage spécifique
>>> b'Ah' 
  File "<ipython-input-2-c12eb8e58bcd>", line 1
    b'Ah'
        ^
SyntaxError: bytes can only contain ASCII literal characters.

>>> 'Ah'.encode('utf-8') #Chaîne->Chaîne d'octets(Encoder)
Out[3]: b'\xe3\x81\x82'


>>> 'Ah' #Chaîne
Out[4]: 'Ah'

>>> b'\xe3\x81\x82'.decode('utf-8') #Chaîne d'octets->Chaîne(Décoder)
Out[5]: 'Ah'


# Python2(Republier)
(py2.7)~ » ipython
   (réduction)
>>> 'Ah' #Chaîne d'octets
Out[1]: '\xe3\x81\x82'

>>> u'Ah' #Chaîne Unicode
Out[2]: u'\u3042'

>>> 'Ah'.decode('utf-8') (or unicode('Ah', 'utf-8')) #Chaîne d'octets->Chaîne Unicode(=Décoder)
Out[3]: u'\u3042'

>>> u'Ah'.encode('utf-8') #Chaîne Unicode->Chaîne d'octets(=Encoder)
Out[4]: '\xe3\x81\x82'

Si vous vérifiez avec la fonction type, vous pouvez voir que la chaîne d'octets est de type octets / la chaîne de caractères est de type str.

python


>>> type(b'a')
Out[6]: bytes #≒ Type de chaîne Python2

>>> type('a')
Out[7]: str #≒ Type unicode Python2

De plus, comme mentionné ci-dessus, les chaînes d'octets Python3 ne sont pas des "chaînes de caractères". Par conséquent, il ne peut pas être concaténé avec une chaîne de caractères et les méthodes prises en charge sont différentes. Ce point est relativement important, car il s'agit de la même chaîne de caractères que dans Python2, le traitement progresse en quelque sorte et finalement "UnicodeEncodeError is ga", mais en Python3 cela devient "erreur due à un type différent" et sortie d'erreur / Le lieu de l'événement est relativement facile à comprendre.

python


>>> s = 'str' #Chaîne

>>> b = b'byte' #Chaîne d'octets

>>> s + b #Chaîne+La chaîne d'octets est une erreur
---------------------------------------------------------------------------
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') #La chaîne prend en charge la méthode find
Out[11]: 1

>>> b.find('y') #La chaîne d'octets ne prend pas en charge la méthode find.
---------------------------------------------------------------------------
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

De plus, à partir de Python 3.2, il semble sélectionner la méthode de codage appropriée à partir de la valeur de locale même lorsque la sortie standard est connectée à un autre que le terminal. Par conséquent, dans Python2, les cas suivants avec UnicodeEncodeError fonctionnent également normalement.

(réf.) http://methane.hatenablog.jp/entry/20120806/1344269400 Addendum

python


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

print('Ah' + 'Dire')


#Exécuter dans le terminal(L'entrée / sortie standard est connectée à la borne)
(py3.4)~ » python test.py
Ah

#Rediriger vers le fichier(L'entrée / sortie standard est connectée à une autre que la borne)
(py3.4)~ » python test.py > test.txt
(py3.4)~ » cat test.txt
Ah

UnicodeEncodeError n'est plus effrayant

Même si vous ne signalez pas de manière flagrante votre mort, vous pouvez toujours rencontrer une erreur UnicodeEncodeError. Par exemple, lors de l'exécution à partir de cron, vous ne pouvez pas sélectionner la méthode de codage à partir des paramètres régionaux et essayer d'encoder / décoder avec ASCII, et vous vous retrouvez généralement avec UnicodeEncodeError.

(ref.) http://www.python.jp/pipermail/python-ml-jp/2014-November/011311.html (La publication est extrêmement opportune)

Compte tenu de cela, il peut être préférable de toujours spécifier la méthode de codage avec la variable d'environnement PYTHONIOENCODING sans compter sur les paramètres régionaux.

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

Alors que faire lorsque vous traitez avec des octets

Vous pouvez utiliser sys.stdin.buffer (entrée standard) / sys.stdout.buffer (sortie standard) pour gérer des chaînes d'octets au lieu de chaînes.

python


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

import sys

#print('Ah' + 'Dire') #l'impression est sys.Écrire dans stdout
sys.stdout.write('Ah' + 'Dire' + '\n') # sys.Ecrire une chaîne dans stdout
sys.stdout.buffer.write(('Ah' + 'Dire' + '\n').encode('utf-8')) # sys.stdout.Ecrire une chaîne d'octets dans la mémoire tampon

#Exécuter dans le terminal
(py3.4)~ » python test.py
Ah
Ah

#Rediriger vers le fichier
(py3.4)~ » python test.py > test.txt
(py3.4)~ » cat test.txt
Ah
Ah

Encore une fois, dans Python 3, les octets et les chaînes sont complètement différents. Par conséquent, la chaîne d'octets ne peut pas être écrite dans sys.stdout qui écrit la chaîne de caractères, et la chaîne de caractères ne peut pas être écrite dans sys.stdout.buffer qui écrit la chaîne d'octets.

python


>>> import sys

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

#Flux d'octets(ref. https://docs.python.org/3/library/io.html#io.BufferedWriter)
>>> type(sys.stdout.buffer)
Out[3]: _io.BufferedWriter 

#Impossible d'écrire des octets dans le flux de texte
>>> 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

#Les chaînes ne peuvent pas être écrites dans bytestream
>>> 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

Points à garder à l'esprit lors du traitement des chaînes en Python2
Points à garder à l'esprit lors du traitement des chaînes en Python 3
Points à garder à l'esprit lors du développement d'un robot d'exploration en Python
Points à garder à l'esprit lors de la copie de listes Python
Précautions lors de l'utilisation de Python avec AtCoder
Choses à garder à l'esprit lors de l'utilisation de cgi avec python.
Points à garder à l'esprit lors de l'utilisation de Python pour ceux qui utilisent MATLAB
Points à garder à l'esprit lors de la création d'outils automatisés pour l'atelier en Python
Points à garder à l'esprit lors du déploiement de Keras sur votre Mac
Points à garder à l'esprit lors de la conversion d'un vecteur de ligne en vecteur de colonne avec ndarray
Choses à noter lors de l'initialisation d'une liste en Python
Choses à surveiller lors de l'utilisation d'arguments par défaut en Python
3 façons d'analyser les chaînes de temps avec python [Note]
Une manière intelligente de chronométrer le traitement avec Python
Erreur lors de la tentative d'installation de psycopg2 en Python
Traitement de fichiers en Python
Traitement multithread en python
Traitement des requêtes en Python
Comparer des chaînes en Python
Inverser les chaînes en Python
Comment prendre plusieurs arguments lors d'un traitement parallèle à l'aide du multitraitement en python
Comment mesurer le temps de traitement avec Python ou Java
Je veux faire quelque chose avec Python à la fin
Je veux manipuler des chaînes dans Kotlin comme Python!
Traitement de texte UTF8 avec python
Pour vider stdout en Python
Traitement asynchrone (threading) en python
Attention lorsque os.mkdir en Python
Parler avec Python [synthèse vocale]
Collection de traitement d'image en Python
Comment développer en Python
Utilisation du mode Python dans le traitement
Publier sur Slack en Python
traitement python3 qui semble utilisable dans paiza
Ce à quoi j'étais accro lorsque l'utilisateur de traitement est passé à Python
Méthode d'écriture pratique lors de l'ajout continu à la liste en Python
Que faire lorsque "SSL: CERTIFICATE_VERIFY_FAILED _ssl.c: 1056" apparaît en Python
Autoriser Python à sélectionner la chaîne de caractères du fichier d'entrée dans le dossier
Ordre de traitement lors du chaînage dans PySpark
[Sous-processus] Lorsque vous souhaitez exécuter un autre programme Python en code Python
Laissez le traitement gênant à Python
[Python] Comment faire PCA avec Python
traitement pour utiliser les données notMNIST en Python (et essayé de les classer)
Précautions lors de l'utilisation de Pit avec Python
Convertir Markdown en PDF en Python
Comment collecter des images en Python
100 Language Processing Knock Chapitre 1 en Python
Comportement lors de la liste dans Python heapq
[Introduction à Python3 Jour 13] Chapitre 7 Chaînes de caractères (7.1-7.1.1.1)
Précautions lors de l'exécution de Python sur EC2 à partir d'AWS Lambda (Exécuter la commande)
Dans la commande python, python pointe vers python3.8
[Introduction à Python3 Jour 14] Chapitre 7 Chaînes de caractères (7.1.1.1 à 7.1.1.4)
Spécification du fuseau horaire lors de la conversion d'une chaîne de caractères en type datetime avec python
[Python] Lorsque vous souhaitez utiliser toutes les variables dans un autre fichier
Essayez de calculer Trace en Python
[Introduction à Python3 Jour 15] Chapitre 7 Chaînes de caractères (7.1.2-7.1.2.2)
Comment utiliser Mysql avec python
Comment envelopper C en Python
Comment utiliser ChemSpider en Python
Comment utiliser PubChem avec Python