as3:~/ngokevin-site# nano content/blog/20140114_test-chinese.mkd
as3:~/ngokevin-site# wok
Traceback (most recent call last):
File "/usr/local/bin/wok", line 4, in
Engine()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 104, in init
self.load_pages()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 238, in load_pages
p = Page.from_file(os.path.join(root, f), self.options, self, renderer)
File "/usr/local/lib/python2.7/site-packages/wok/page.py", line 111, in from_file
page.meta['content'] = page.renderer.render(page.original)
File "/usr/local/lib/python2.7/site-packages/wok/renderers.py", line 46, in render
return markdown(plain, Markdown.plugins)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 419, in markdown
return md.convert(text)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 281, in convert
source = unicode(source)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 1: ordinal not in range(128). -- Note: Markdown only accepts unicode input!고치는 방법?
다른 파이썬 기반 정적 블로그 앱에서 중국어 게시물을 성공적으로 게시 할 수 있습니다. 이 응용 프로그램과 같은 : http://github.com/vrypan/bucket3 . 내 사이트 http://bc3.brite.biz/ 에서 중국어 게시물을 성공적으로 게시 할 수 있습니다.
답변
tl; dr / 빠른 수정
- Willy Nilly를 디코딩 / 인코딩하지 마십시오
- 문자열이 UTF-8로 인코딩되어 있다고 가정하지 마십시오
- 코드에서 가능한 빨리 문자열을 유니 코드 문자열로 변환하십시오.
- 로케일을 수정하십시오. Python 3.6에서 UnicodeDecodeError를 해결하는 방법?
- 빠른 reload해킹 을 사용하려는 유혹을받지 마십시오
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과 마찬가지로 유니 코드로 작업하십시오.
산출
표준 출력 / 인쇄
printstdout 스트림을 통해 씁니다. 파이썬은 유니 코드가 콘솔의 인코딩으로 인코딩되도록 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”)을 사용하지 않아야하는 이유를 참조하십시오 . 자세한 내용은
답변
마침내 나는 그것을 얻었다 :
as3:/usr/local/lib/python2.7/site-packages# cat sitecustomize.py
# encoding=utf8  
import sys
reload(sys)
sys.setdefaultencoding('utf8')내가 체크해 볼게:
as3:~/ngokevin-site# python
Python 2.7.6 (default, Dec  6 2013, 14:49:02)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.getdefaultencoding()
'utf8'
>>>위의 python의 기본 인코딩은입니다 utf8. 그렇다면 오류는 더 이상 없습니다.
답변
이것은 고전적인 “유니 코드 문제”입니다. 나는 이것을 설명하는 것이 무슨 일인지 완전히 설명하기 위해 StackOverflow 답변의 범위를 벗어난 것이라고 생각합니다.
여기에 잘 설명되어 있습니다 .
간단히 요약하면 바이트 문자열로 해석되는 것을 유니 코드 문자로 디코딩해야하는 것으로 전달했지만 기본 코덱 (ascii)은 실패합니다.
이것을 피하기위한 조언을 해주겠다고 지시 한 프레젠테이션. 코드를 “유니 코드 샌드위치”로 만드십시오. 파이썬 2에서는 from __future__ import unicode_literals도움을 사용 합니다.
업데이트 : 코드를 수정하는 방법 :
OK – 변수 “source”에 약간의 바이트가 있습니다. 귀하의 질문에 그들이 어떻게 들어 왔는지는 분명하지 않습니다. 아마도 웹 양식에서 읽을 수 있습니까? 어쨌든 그들은 ascii로 인코딩되지 않지만 파이썬은 그것들을 가정하여 유니 코드로 변환하려고합니다. 인코딩이 무엇인지 명시 적으로 알려 주어야합니다. 이것은 인코딩이 무엇인지 알아야 한다는 것을 의미합니다 ! 항상 쉬운 것은 아니며이 문자열의 출처에 전적으로 달려 있습니다. UTF-8과 같은 일반적인 인코딩을 실험 해 볼 수 있습니다. unicode ()에게 두 번째 매개 변수로 인코딩을 알려줍니다.
source = unicode(source, 'utf-8')답변
경우에 따라 기본 인코딩 ( print sys.getdefaultencoding()) 을 확인 하면 ASCII를 사용하고 있음을 반환합니다. UTF-8로 변경하면 변수의 내용에 따라 작동하지 않습니다. 다른 방법을 찾았습니다.    
import sys
reload(sys)
sys.setdefaultencoding('Cp1252')답변
다음 오류 메시지를 해결하기 위해 검색했습니다.
unicodedecodeerror : ‘ascii’코덱이 5454 위치에서 바이트 0xe2를 디코딩 할 수 없습니다 : 서 수가 범위 내에 있지 않습니다 (128)
마침내 ‘encoding’을 지정하여 수정했습니다.
f = open('../glove/glove.6B.100d.txt', encoding="utf-8")그것이 당신을 도울 수 있기를 바랍니다.
답변
"UnicodeDecodeError: 'ascii' codec can't decode byte"이 오류의 원인 : input_string은 유니 코드 여야하지만 str이 제공되었습니다.
"TypeError: Decoding Unicode is not supported"이 오류의 원인 : 유니 코드 input_string을 유니 코드로 변환하려고합니다.
따라서 먼저 input_string이 있는지 확인하고 str필요한 경우 유니 코드로 변환하십시오.
if isinstance(input_string, str):
   input_string = unicode(input_string, 'utf-8')둘째, 위의 유형 만 변경하지만 ASCII가 아닌 문자는 제거하지 않습니다. ASCII가 아닌 문자를 제거하려는 경우 :
if isinstance(input_string, str):
   input_string = input_string.decode('ascii', 'ignore').encode('ascii') #note: this removes the character and encodes back to string.
elif isinstance(input_string, unicode):
   input_string = input_string.encode('ascii', 'ignore')답변
나는 항상 유니 코드로 변환하는 것이 가장 좋다는 것을 알지만 실제로는 모든 인수를 확인하고 문자열 처리 형식을 포함하는 모든 함수 및 메소드로 변환해야하기 때문에 달성하기가 어렵습니다.
그래서 두 입력 중 하나에서 유니 코드 또는 바이트 문자열을 보장하기 위해 다음과 같은 접근법을 생각해 냈습니다. 간단히 말해 다음 람다를 포함하여 사용 하십시오.
# guarantee unicode string
_u = lambda t: t.decode('UTF-8', 'replace') if isinstance(t, str) else t
_uu = lambda *tt: tuple(_u(t) for t in tt)
# guarantee byte string in UTF8 encoding
_u8 = lambda t: t.encode('UTF-8', 'replace') if isinstance(t, unicode) else t
_uu8 = lambda *tt: tuple(_u8(t) for t in tt)예 :
text='Some string with codes > 127, like Zürich'
utext=u'Some string with codes > 127, like Zürich'
print "==> with _u, _uu"
print _u(text), type(_u(text))
print _u(utext), type(_u(utext))
print _uu(text, utext), type(_uu(text, utext))
print "==> with u8, uu8"
print _u8(text), type(_u8(text))
print _u8(utext), type(_u8(utext))
print _uu8(text, utext), type(_uu8(text, utext))
# with % formatting, always use _u() and _uu()
print "Some unknown input %s" % _u(text)
print "Multiple inputs %s, %s" % _uu(text, text)
# but with string.format be sure to always work with unicode strings
print u"Also works with formats: {}".format(_u(text))
print u"Also works with formats: {},{}".format(*_uu(text, text))
# ... or use _u8 and _uu8, because string.format expects byte strings
print "Also works with formats: {}".format(_u8(text))
print "Also works with formats: {},{}".format(*_uu8(text, text))
