Avant-propos
Récemment, en raison des besoins du projet, j'ai besoin de lire un document txt contenant des caractères chinois, et après cela, je dois enregistrer le fichier. Le document était auparavant codé en base64, ce qui faisait que tous les caractères chinois étaient lus et affichés sous forme de caractères tronqués. Après que l'équipe du projet a abandonné base64, deux erreurs se sont produites successivement :
ascii codec can't encode characters in position ordinal not in range 128 UnicodeDecodeError: ‘utf8' codec can't decode byte 0x。
Si vous ne connaissez pas ascii, unicode et utf-8, vous pouvez lisez cet article précédent sur les chaînes et l'encodage
Ensuite, vous devez comprendre les trois concepts suivants :
ascii uniquement Peut représenter des chiffres, des lettres anglaises et certains symboles spéciaux, mais ne peuvent pas représenter les caractères chinois
Unicode et utf-8 peuvent représenter des caractères chinois, l'unicode est une longueur fixe et utf-8 est une longueur variable
La méthode de stockage en mémoire est généralement Unicode, tandis que la méthode de stockage des fichiers sur disque est généralement utf-8, car utf-8 peut économiser de l'espace de stockage
Alors quel est l'encodage par défaut de python ?
>>> import sys >>> sys.getdefaultencoding() 'ascii' >>> reload(sys) <module 'sys' (built-in)> >>> sys.setdefaultencoding('utf-8') >>> sys.getdefaultencoding() 'utf-8'
L'encodage par défaut de python est ascii, et vous pouvez définir l'encodage par défaut de python via la fonction sys.setdefaultencoding('utf-8')
.
En python, vous pouvez modifier l'encodage des données via l'encodage et le décodage, par exemple :
>>> u'汉字' u'\u6c49\u5b57' >>> u'汉字'.encode('utf-8') '\xe6\xb1\x89\xe5\xad\x97' >>> u'汉字'.encode('utf-8').decode('utf-8') u'\u6c49\u5b57'
Nous pouvons utiliser ces deux fonctions Définir l'encodage.
Alors, quel est le type str en python ?
>>> import binascii >>> '汉字' '\xba\xba\xd7\xd6' >>> type('汉字') <type 'str'> >>> print binascii.b2a_hex('汉字') babad7d6 >>> print binascii.b2a_hex(u'汉字') Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128) >>> print binascii.b2a_hex(u'汉字'.encode('utf-8')) e6b189e5ad97 >>> print binascii.b2a_hex(u'汉字'.encode('gbk')) babad7d6
binascii convertit le binaire des données en ascii L'explication ci-dessus est la suivante : le type de "caractères chinois" est str, et le Le binaire est babad7d6 , le « caractère chinois » ne peut pas être converti en ascii, donc la première erreur au début est signalée. La solution est de le .encode('utf-8') en type str. Étant donné que ma ligne de commande utilise le codage GBK par défaut de Windows, lorsque tous les « caractères chinois » .encode(‘gbk')
apparaissent, les résultats de sortie sont les mêmes que les résultats des « caractères chinois ».
Pour résumer, le str de python est en fait un type d'unicode. Le codage par défaut de python est ascii. Lors de la conversion de non-ascii en ascii, une erreur sera signalée :
<🎜. >import sys reloads(sys) sys.setdefaultencoding('utf-8')
import codecs codecs.open(file_name, "r",encoding='utf-8', errors='ignore')