С этой статьей программирование на Python больше не будет кошмаром

Python

Впервые опубликовано в личном общедоступном аккаунте: «Время программирования на Python».

Оригинальный текст моего блога:Python.is для BM.com/en/latest/ от…

Мой гитхаб:GitHub.com/is BM/py, хотя…


Проблемы с кодированием на Python всегда были ночным кошмаром для многих Python-разработчиков.Хоть вы и являетесь Python-разработчиком, проработавшим много лет, вы обязательно столкнетесь с надоедливыми проблемами кодирования.На то, чтобы разобраться в этом, ушло много времени.

Через какой-то период времени все они снова забываются, и вы снова начинаете искать различные блоги и посты, и выяснять, что такое кодинг, с нуля? Что такое юникод? Чем он отличается от ASCII? Почему decode encode всегда сообщает об ошибке? Почему типы строк в python2 и python3 разные, как они соотносятся? Как определить формат кодировки?

Снова и снова этот процесс действительно болезненный.

Сегодня я объяснил некоторые проблемы с кодированием, с которыми вы столкнетесь на Python.В будущем вы можете сохранить эту статью без Google.

1. строка и байты в Python 3

В Python3 строки имеют два типа: str и bytes.

Сегодня поговорим о разнице между ними:

  • unicode string(str 类型): хранится в виде кодовых точек Unicode,форма человеческого познания
  • byte string(bytes 类型): хранится в байтовой форме,Формы машинного распознавания

Все строки, которые вы определяете в Python 3, имеют тип строки Unicode, используйтеtypeа такжеisinstanceможно дискриминировать

# python3

>>> str_obj = "你好"
>>> 
>>> type(str_obj)
<class 'str'>
>>> 
>>> isinstance("你好", str)
True
>>> 
>>> isinstance("你好", bytes)
False
>>> 

И байты - это объект двоичной последовательности, вам нужно только добавить строку перед ним, когда вы его определяете.b, это означает, что вы хотите определить строковый объект типа bytes.

# python3
>>> byte_obj = b"Hello World!"
>>> type(byte_obj)
<class 'bytes'>
>>> 
>>> isinstance(byte_obj, str)
False
>>> 
>>> isinstance(byte_obj, bytes)
True
>>> 

Но при определении китайских строк вы не можете напрямую добавитьb, вместо этого вы должны использоватьencodeПоверни это другой стороной.

>>> byte_obj=b"你好"
  File "<stdin>", line 1
SyntaxError: bytes can only contain ASCII literal characters.
>>> 
>>> str_obj="你好"
>>> 
>>> str_obj.encode("utf-8")
b'\xe4\xbd\xa0\xe5\xa5\xbd'
>>> 

2. str и юникод в Python 2

В Python2 тип строки отличается от Python3, и его необходимо тщательно различать.

В Python2 есть только два типа строк: unicode и str.

Только разница между объектом unicode и объектом, отличным от unicode (он должен называться объектом str):

  • unicode string(unicode类型): хранится в виде кодовых точек Unicode,форма человеческого познания
  • byte string(str 类型): хранится в байтовой форме,Формы машинного распознавания

Когда мы напрямую используем двойные кавычки или одинарные кавычки, чтобы содержать символы для определения строки, это объект строки str, такой как этот

# python2

>>> str_obj="你好"
>>>
>>> type(str_obj)
<type 'str'>
>>>
>>> str_obj
'\xe4\xbd\xa0\xe5\xa5\xbd'
>>>
>>> isinstance(str_obj, bytes)
True
>>> isinstance(str_obj, str)
True
>>> isinstance(str_obj, unicode)
False
>>>
>>> str is bytes
True

И когда мы добавляем двойную или одинарную кавычку передu, указывая, что мы определяем строковый объект юникода, такой как этот

# python2

>>> unicode_obj = u"你好"
>>>
>>> unicode_obj
u'\u4f60\u597d'
>>>
>>> type(unicode_obj)
<type 'unicode'>
>>>
>>> isinstance(unicode_obj, bytes)
False
>>> isinstance(unicode_obj, str)
False
>>>
>>> isinstance(unicode_obj, unicode)
True

3. Как определить кодировку объекта

Все символы имеют соответствующие значения кодировки в наборе символов юникода (в английском языке это называется:code point)

А сохранение этих закодированных значений в бинарные байткоды по определенным правилам и есть то, что мы называем методом кодирования, распространенными являются: UTF-8, GB2312 и т.д.

То есть, когда мы хотим сохранить строку в памяти на жесткий диск, мы должны указать метод кодирования, и наоборот, при чтении мы также должны указать правильный метод кодирования (этот процесс называется декодированием), иначе, появятся искаженные символы.

Тогда возникает проблема, когда мы знаем соответствующий метод кодирования, мы можем нормально декодировать, но не все время мы можем знать, какой метод кодирования следует использовать для декодирования?

В это время мы представим библиотеку Python —chardet, вам необходимо установить его перед использованием

python3 -m pip install chardet

Charde имеет метод обнаружения, который может预测его формат кодирования

>>> import chardet
>>> chardet.detect('微信公众号:Python编程时光'.encode('gbk'))
{'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}

Почему это предсказывается приведенной выше точкой зрения вывода, вы увидите, что есть поле достоверности, которое представляет прогноз достоверности или коэффициент успеха.

Но при его использовании, если у вас небольшое количество символов, есть возможность "误诊"), например, только中文Два слова, как следующие: мы используем кодировку gbk, но используем chardet, но распознаем ее как кодировку KOI8-R.

>>> str_obj = "中文"
>>> byte_obj = bytes(a, encoding='gbk')  # 先得到一个 gbk 编码的 bytes
>>>
>>> chardet.detect(byte_obj)
{'encoding': 'KOI8-R', 'confidence': 0.682639754276994, 'language': 'Russian'}
>>> 
>>> str_obj2 = str(byte_obj, encoding='KOI8-R')
>>> str_obj2
'жпнд'

Поэтому, чтобы точно закодировать диагноз, старайтесь использовать как можно больше символов.

chardet поддерживает несколько языков.Из официальной документации видно, что поддерживаются следующие языки (Вставленный рисунок читайте в документе s.io/ru/latest/...)

4. Разница между кодированием и декодированием

Кодирование и декодирование — это на самом деле процесс взаимного преобразования между str и bytes (Python 2 ушел, а здесь и далее используется только Python 3)

  • кодирование: метод кодирования, который преобразует строковый объект в двоичную последовательность байтов.

  • расшифровка: метод декодирования, который преобразует двоичную последовательность байтов в строковый объект.

Поэтому, если мы действительно знаем его формат кодирования, как мы преобразуем его в Unicode?

Есть два способа

ПервыйДа, используйте метод декодирования напрямую

>>> byte_obj.decode('gbk')
'中文'
>>> 

второйДа, используйте класс str для преобразования

>>> str_obj = str(byte_obj, encoding='gbk')
>>> str_obj
'中文'
>>> 

5. Как установить кодировку файла

В Python 2 кодировка ASCII используется по умолчанию для чтения, поэтому, когда мы используем Python 2, если ваш файл python содержит китайский язык, операция сообщит об ошибке.

SyntaxError: Non-ASCII character '\xe4' in file demo.py

Причина в том, что таблица кодировки ASCII слишком мала для интерпретации китайского языка.

В Python3 для чтения по умолчанию используется utf-8, поэтому многое сохраняется.

Обычно есть два решения этой проблемы:

первый метод

В python2 вы можете использовать указанный заголовок

Можно так написать, хотя красиво

# -*- coding: utf-8 -*- 

Но писать таким образом слишком хлопотно, я обычно использую следующие два способа записи

# coding:utf-8
# coding=utf-8 

Второй способ

import sys 

reload(sys) 
sys.setdefaultencoding('utf-8') 

Здесь перед вызовом sys.setdefaultencoding('utf-8') для установки метода декодирования по умолчанию выполняется reload(sys), что необходимо, поскольку python удалит метод sys.setdefaultencoding('utf-8') для установки метода декодирования по умолчанию, что необходимо, поскольку python удалит метод sys.setdefaultencoding('utf-8') для вызовите метод sys.setdefaultencoding.


关注公众号,获取最新干货!