tl; dr / 빠른 수정
Python 2.x의 유니 코드 젠-긴 버전
소스를 보지 않으면 근본 원인을 알기가 어렵 기 때문에 일반적으로 말해야합니다.
UnicodeDecodeError: 'ascii' codec can't decode byte
일반적으로 Python 2.x를 변환하려고 할 때 발생합니다. str
원래 문자열의 인코딩을 지정하지 않고 비 ASCII가 포함 를 유니 코드 문자열 합니다.
간단히 말해서, 유니 코드 문자열은 인코딩을 포함하지 않는 완전히 분리 된 유형의 파이썬 문자열입니다. 유니 코드 포인트 코드 만 보유 하므로 전체 스펙트럼에서 유니 코드 포인트를 보유 할 수 있습니다. 인코딩 된 텍스트 스트링을 포함 베이트 UTF-8, UTF-16, ISO-8895-1, GBK, 등의 Big5 문자열이 유니 코드 디코딩 및 문자열로 인코딩 Unicodes . 파일과 텍스트 데이터는 항상 인코딩 된 문자열로 전송됩니다.
Markdown 모듈 작성자 unicode()
는 나머지 코드의 품질 게이트로 예외 (예외가 발생한 경우)를 사용합니다. ASCII를 변환하거나 기존 유니 코드 문자열을 새 유니 코드 문자열로 다시 랩핑합니다. Markdown 작성자는 들어오는 문자열의 인코딩을 알 수 없으므로 Markdown으로 전달하기 전에 문자열을 유니 코드 문자열로 디코딩해야합니다.
문자열에 u
접두사를 사용하여 코드에서 유니 코드 문자열을 선언 할 수 있습니다 . 예 :
>>> my_u = u'my ünicôdé strįng'
>>> type(my_u)
<type 'unicode'>
유니 코드 문자열은 파일, 데이터베이스 및 네트워크 모듈에서 올 수도 있습니다. 이 경우 인코딩에 대해 걱정할 필요가 없습니다.
잡았다
str
명시 적으로 호출하지 않아도 유니 코드 에서 유니 코드로 변환 할 수 있습니다 unicode()
.
다음과 같은 시나리오에서는 UnicodeDecodeError
예외가 발생합니다.
# Explicit conversion without encoding
unicode('€')
# New style format string into Unicode string
# Python will try to convert value string to Unicode first
u"The currency is: {}".format('€')
# Old style format string into Unicode string
# Python will try to convert value string to Unicode first
u'The currency is: %s' % '€'
# Append string to Unicode
# Python will try to convert string to Unicode first
u'The currency is: ' + '€'
예
다음 다이어그램 café
에서 터미널 유형에 따라 단어 가 "UTF-8"또는 "Cp1252"인코딩으로 인코딩 된 방식을 볼 수 있습니다. 두 예에서 모두 caf
규칙적인 ASCII입니다. UTF-8에서는 é
2 바이트를 사용하여 인코딩됩니다. "Cp1252"에서 é는 0xE9입니다 (이는 유니 코드 포인트 값이기도합니다 (우연의 일치가 아님)). 올바른 decode()
것이 호출되고 Python 유니 코드로 변환이 성공합니다.
이 다이어그램에서 decode()
로 호출됩니다 ascii
( unicode()
인코딩없이 호출하는 것과 동일 ). ASCII는보다 큰 바이트를 포함 할 수 없으므로 예외 0x7F
가 UnicodeDecodeError
발생합니다.
유니 코드 샌드위치
들어오는 모든 데이터를 유니 코드 문자열로 디코딩하고 유니 코드로 작업 한 다음 str
나가는 길로 인코딩하는 코드에 유니 코드 샌드위치를 형성하는 것이 좋습니다 . 이렇게하면 코드 중간에 문자열 인코딩을 걱정할 필요가 없습니다.
입력 / 디코딩
소스 코드
비 ASCII를 소스 코드에 구워야하는 경우 문자열 앞에 접두사를 붙여 유니 코드 문자열을 만드십시오 u
. 예 :
u'Zürich'
파이썬이 소스 코드를 해독 할 수있게하려면 파일의 실제 인코딩과 일치하도록 인코딩 헤더를 추가해야합니다. 예를 들어 파일이 'UTF-8'로 인코딩 된 경우 다음을 사용합니다.
# encoding: utf-8
소스 코드 에 비 ASCII가있는 경우에만 필요 합니다 .
파일
일반적으로 비 ASCII 데이터는 파일에서 수신됩니다. 이 io
모듈은 지정된을 사용하여 파일을 즉시 디코딩하는 TextWrapper를 제공합니다 encoding
. 파일에 올바른 인코딩을 사용해야합니다. 쉽게 추측 할 수 없습니다. 예를 들어, UTF-8 파일의 경우 :
import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
my_unicode_string = my_file.read()
my_unicode_string
그런 다음 Markdown으로 전달하기에 적합합니다. 경우 UnicodeDecodeError
로부터 read()
라인, 그때는 아마 잘못된 인코딩 값을 사용했습니다.
CSV 파일
Python 2.7 CSV 모듈은 비 ASCII 문자를 지원하지 않습니다. 그러나 https://pypi.python.org/pypi/backports.csv의 도움이 필요 합니다.
위와 같이 사용하지만 열린 파일을 전달하십시오.
from backports import csv
import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
for row in csv.reader(my_file):
yield row
데이터베이스
대부분의 Python 데이터베이스 드라이버는 유니 코드로 데이터를 반환 할 수 있지만 일반적으로 약간의 구성이 필요합니다. SQL 쿼리에는 항상 유니 코드 문자열을 사용하십시오.
MySQL
연결 문자열에서 다음을 추가하십시오.
charset='utf8',
use_unicode=True
예 :
>>> db = MySQLdb.connect(host="localhost", user='root', passwd='passwd', db='sandbox', use_unicode=True, charset="utf8")
PostgreSQL
더하다:
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
HTTP
웹 페이지는 거의 모든 인코딩으로 인코딩 될 수 있습니다. Content-type
헤더는 포함해야 charset
부호화 암시하는 필드. 그런 다음이 값에 대해 내용을 수동으로 디코딩 할 수 있습니다. 또는 Python-Requests 는에서 유니 코드를 반환합니다 response.text
.
수동으로
문자열을 수동으로 디코딩해야하는 경우 적절한 인코딩이있는 my_string.decode(encoding)
곳 encoding
이면됩니다. Python 2.x 지원 코덱은 다음과 같습니다. Standard Encodings . 다시 말하지만, UnicodeDecodeError
인코딩이 잘못되었을 수 있습니다.
샌드위치 고기
일반적인 str과 마찬가지로 유니 코드로 작업하십시오.
산출
표준 출력 / 인쇄
print
stdout 스트림을 통해 씁니다. 파이썬은 유니 코드가 콘솔의 인코딩으로 인코딩되도록 stdout에서 인코더를 구성하려고 시도합니다. 예를 들어, Linux 쉘 locale
이 en_GB.UTF-8
인 경우 출력은로 인코딩됩니다 UTF-8
. Windows에서는 8 비트 코드 페이지로 제한됩니다.
손상된 로캘과 같이 잘못 구성된 콘솔은 예기치 않은 인쇄 오류로 이어질 수 있습니다. PYTHONIOENCODING
환경 변수는 stdout 인코딩을 강제 할 수 있습니다.
파일
입력과 마찬가지로 io.open
유니 코드를 인코딩 된 바이트 문자열로 투명하게 변환하는 데 사용할 수 있습니다.
데이터 베이스
동일한 읽기 구성으로 유니 코드를 직접 작성할 수 있습니다.
파이썬 3
Python 3은 더 이상 Python 2.x보다 유니 코드를 사용할 수 없지만 주제에 대해 약간 덜 혼동됩니다. 예를 들어 일반 str
은 이제 유니 코드 문자열이고 이전 str
은 이제 bytes
입니다.
기본 인코딩은 UTF-8이므로 .decode()
인코딩하지 않고 바이트 문자열을 사용하면 Python 3은 UTF-8 인코딩을 사용합니다. 이것은 아마도 사람들의 유니 코드 문제의 50 %를 해결합니다.
또한 open()
기본적으로 텍스트 모드에서 작동하므로 디코딩 된 str
(유니 코드 것)을 반환합니다 . 인코딩은 로케일에서 파생되며, Un * x 시스템의 UTF-8 또는 Windows 상자의 windows-1251와 같은 8 비트 코드 페이지입니다.
왜 사용하지 않아야 하는가 sys.setdefaultencoding('utf8')
reload
문제를 가리고 Python 3.x 로의 마이그레이션을 방해 하는 불쾌한 해킹입니다 (사용해야하는 이유가 있습니다 ). 문제를 이해하고 근본 원인을 해결하고 유니 코드 선을 즐기십시오. py 스크립트에서 sys.setdefaultencoding ( "utf-8")을 사용하지 않아야하는 이유를 참조하십시오 . 자세한 내용은