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!
それを修正するには?
他のPythonベースの静的ブログアプリの中には、中国語の投稿を正常に公開できるものがあります。このアプリのように: http://github.com/vrypan/bucket3 。私のサイト http://bc3.brite.biz/ では、中国の投稿はうまく公開できます。
ついにできた:
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
です。それからエラーはもうありません。
sys.setdefaultencoding('utf8')
)問題を隠し、Python 3.xへの移行を妨げるのは厄介なハックです(reload
を使用する必要がある理由があります)。問題を理解し、根本原因を修正し、そしてUnicodeの禅を楽しんでください。 を参照してください。 詳細はこちら
原因が分からなければ根本的な原因を知るのは難しいので、一般的に話さなければなりません。
UnicodeDecodeError: 'ascii' codec can't decode byte
は一般に、元の文字列のエンコーディングを指定せずに、非ASCII文字を含むPython 2.x str
をUnicode文字列に変換しようとしたときに発生します。
簡単に言うと、Unicode文字列は、まったく別の種類のPython文字列で、エンコーディングは含まれていません。これらはUnicode ポイントコードのみを保持しているため、スペクトル全体からの任意のUnicodeポイントを保持できます。文字列はUTF-8、UTF-16、ISO-8895-1、GBK、Big5などのエンコードされたテキストを含みます。ストリングはUnicodeにデコードされ、Unicodeはストリングにエンコードされます。ファイルとテキストデータは常にエンコードされた文字列で転送されます。
Markdownモジュールの作者は、おそらくunicode()
(例外がスローされる場所)を残りのコードへの良質の門として使うでしょう - それはASCIIを変換するか、または既存のUnicode文字列を新しいUnicode文字列に再ラップします。 Markdownの作者は入力文字列のエンコーディングを知ることができないので、Markdownに渡す前に文字列をUnicode文字列にデコードするのはあなたに頼ります。
Unicode文字列は、文字列の接頭辞u
を使用してコード内で宣言できます。例えば。
>>> my_u = u'my ünicôdé strįng'
>>> type(my_u)
<type 'unicode'>
Unicode文字列はファイル、データベース、ネットワークモジュールからも来ます。こうなっても、エンコーディングについて心配する必要はありません。
明示的に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: ' + '€'
次の図では、端末の種類に応じてWord café
が "UTF-8"または "Cp1252"エンコーディングでエンコードされていることがわかります。両方の例で、caf
は通常のASCIIです。 UTF-8では、é
は2バイトを使用してエンコードされます。 "Cp1252"では、éは0xE9です(これはUnicodeのポイント値でもあります(偶然の一致ではありません))。正しいdecode()
が呼び出され、Python Unicodeへの変換は成功しました:
この図では、decode()
はascii
で呼び出されています(これは、エンコーディングを指定せずにunicode()
を呼び出すのと同じです)。 ASCIIは0x7F
より大きなバイトを含むことができないので、これはUnicodeDecodeError
例外を投げます:
コードにUnicodeサンドイッチを作成して、すべての受信データをUnicode文字列にデコードし、Unicodeを使用してから、途中でstr
sにエンコードすることをお勧めします。これにより、コードの途中での文字列のエンコードについて心配する必要がなくなります。
あなたのソースコードに非ASCII文字を焼き付ける必要がある場合は、文字列の先頭にu
を付けてUnicode文字列を作成してください。例えば。
u'Zürich'
Pythonでソースコードをデコードできるようにするには、ファイルの実際のエンコードと一致するようにエンコードヘッダーを追加する必要があります。たとえば、ファイルが「UTF-8」としてエンコードされている場合は、次のようにします。
# encoding: utf-8
これはあなたのソースコードに非ASCIIコードがある場合にのみ必要です。
通常、非ASCIIデータはファイルから受信されます。 io
モジュールは、与えられたencoding
を使ってファイルをオンザフライでデコードするTextWrapperを提供します。ファイルには正しいエンコードを使用する必要があります - 簡単に推測することはできません。たとえば、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に渡すのに適しています。 read()
行のUnicodeDecodeError
の場合は、おそらく間違ったエンコード値を使用したことになります。
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データベースドライバはUnicodeでデータを返すことができますが、通常は少し設定が必要です。 SQLクエリには常にUnicode文字列を使用してください。
接続文字列に以下を追加します。
charset='utf8',
use_unicode=True
例えば。
>>> db = MySQLdb.connect(Host="localhost", user='root', passwd='passwd', db='sandbox', use_unicode=True, charset="utf8")
追加:
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
Webページは、ほぼあらゆるエンコード方式でエンコードできます。 Content-type
ヘッダーには、エンコーディングを暗示するためのcharset
フィールドを含める必要があります。コンテンツはこの値に対して手動でデコードできます。あるいは、 Python-Requests はUnicodeをresponse.text
に返します。
文字列を手動でデコードする必要がある場合は、単にmy_string.decode(encoding)
を実行できます。ここでencoding
は適切なエンコードです。 Python 2.xでサポートされているコーデックはここにあります: 標準エンコーディング 。繰り返しますが、UnicodeDecodeError
を取得した場合は、おそらく間違ったエンコーディングを使用しているはずです。
通常のstrsと同じようにUnicodeを操作します。
print
は、標準出力ストリームを介して書き込みます。 Pythonは、Unicodeがコンソールのエンコーディングにエンコードされるように、標準出力にエンコーダーを設定しようとします。たとえば、Linuxシェルのlocale
がen_GB.UTF-8
の場合、出力はUTF-8
にエンコードされます。 Windowsでは、8ビットコードページに制限されます。
ロケールの破損など、コンソールの設定が正しくないと、予期しない印刷エラーが発生する可能性があります。 PYTHONIOENCODING
環境変数は標準出力のエンコーディングを強制することができます。
入力と同様に、io.open
を使用してUnicodeをエンコードされたバイト文字列に透過的に変換することができます。
読み取りと同じ設定で、Unicodeを直接書き込むことができます。
Python 3では、Python 2.xと同等のUnicode対応はできませんが、通常のstr
はUnicode文字列になり、古いstr
はbytes
になります。
デフォルトのエンコーディングはUTF-8になりました。エンコーディングを指定せずにバイト文字列を.decode()
と指定した場合、Python 3はUTF-8エンコーディングを使用します。これはおそらく人々のUnicodeの問題の50%を修正しています。
さらに、open()
はデフォルトでテキストモードで動作するので、デコードされたstr
(Unicodeの1)を返します。エンコーディングはロケールに由来します。ロケールは、Un * xシステムではUTF-8、Windowsボックスではwindows-1251などの8ビットコードページです。
これが古典的な「Unicodeの問題」です。これを説明することは、何が起こっているのかを完全に説明するためのStackOverflow回答の範囲を超えていると思います。
よく説明されている ここ 。
非常に簡単に要約すると、バイト文字列として解釈されるものをUnicode文字にデコードする必要があるものに渡しましたが、デフォルトのコーデック(ascii)が失敗しています。
あなたが指し示したプレゼンテーションはこれを避けるためのアドバイスを提供します。コードを「Unicodeサンドイッチ」にします。 Python 2では、 "from __future__ import unicode_literals"の使用が役に立ちます。
更新日:どのようにコードを修正することができます:
OK - あなたの変数の "source"には数バイトあります。彼らがどのようにしてそこに入ったかはあなたの質問からは明らかではありません - 多分あなたはそれらをウェブフォームから読んだ?いずれにせよ、それらはASCIIでエンコードされていませんが、pythonはそれらがUnicodeであると仮定してUnicodeに変換しようとしています。エンコーディングとは何かを明示的に伝える必要があります。これはあなたが 知る必要があることを意味します エンコーディングは何ですか!それは必ずしも容易ではありません、そしてそれは完全にこの文字列がどこから来たのかに依存します。 UTF-8など、いくつかの一般的なエンコーディングを試すことができます。 2番目のパラメータとしてエンコードをunicode()に伝えます。
source = unicode(source, 'utf-8')
場合によっては、デフォルトのエンコーディング(print sys.getdefaultencoding()
)を確認すると、ASCIIを使用していることが返されます。あなたがUTF-8に変更した場合、それはあなたの変数の内容によってはうまくいきません。
import sys
reload(sys)
sys.setdefaultencoding('Cp1252')
"UnicodeDecodeError: 'ascii' codec can't decode byte"
このエラーの原因:input_stringはUnicodeである必要がありますが、strが指定されています
"TypeError: Decoding Unicode is not supported"
このエラーの原因:Unicode input_stringをUnicodeに変換しようとしています
それで最初にあなたのinput_stringがstr
であることを確認し、必要ならばUnicodeに変換してください:
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')
次のエラーメッセージを解決するために探していました。
unicodedecodeerror: 'ascii'コーデックが位置5454のバイト0xe2をデコードできない:序数が範囲外(128)
私はついに 'encoding'を指定することでそれを直しました:
f = open('../glove/glove.6B.100d.txt', encoding="utf-8")
それがあなたにも役立つことを願っています。
常にUnicodeに変換するのが最善だと思いますが、実際には、すべての引数をチェックして、何らかの形式の文字列処理を含むすべての関数やメソッドに変換する必要があるため、これを達成するのは困難です。
そこで、どちらの入力からもUnicodeまたはバイト文字列を保証するために、次のようなアプローチを思いつきました。手短に言うと、 以下のラムダを含めて 使用します。
# 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))
これがもう少しあります これについての推論 。
Encodeは、Unicodeオブジェクトを文字列オブジェクトに変換します。文字列オブジェクトをエンコードしようとしていると思います。まず結果をUnicodeオブジェクトに変換してから、そのUnicodeオブジェクトを 'utf-8'にエンコードします。例えば
result = yourFunction()
result.decode().encode('utf-8')
私は同じ問題を抱えていましたが、Python 3ではうまくいきませんでした。
enc = sys.getdefaultencoding()
file = open(menu, "r", encoding = enc)
ファイルを読み書きするときにはエンコーディングを設定する必要があります。
要するに、Python 2で正しいUnicode処理を保証するためには、
io.open
を使うfrom __future__ import unicode_literals
を使うprint(text.encode('ascii', 'replace').decode())
説明については、@ Alastair McCormackの 詳細な回答 を参照してください。
私は文字列 "PastelerãaMallorca"と同じ問題を抱えて、私はと解決した:
unicode("PastelerÃa Mallorca", 'latin-1')
このエラーは、文字列にASCII以外の文字が含まれていて、適切なデコードを行わずにその文字列に対して操作を実行している場合に発生します。以下のように、列ID、テキスト、およびデコード文字を含むCSVファイルを読み込んでいます。
train_df = pd.read_csv("Example.csv")
train_data = train_df.values
for i in train_data:
print("ID :" + i[0])
text = i[1].decode("utf-8",errors="ignore").strip().lower()
print("Text: " + text)
Django(1.9.10)/ Python 2.7.5プロジェクトでは、頻繁にUnicodeDecodeError
例外があります。主に、Unicode文字列をロギングに入力しようとしたときです。私は基本的に8ビットのアスキー文字列にフォーマットし、 '?'にない文字を置き換えるために任意のオブジェクトのためのヘルパー関数を作りました。私はそれが最善の解決策ではないと思いますが、デフォルトのエンコーディングはASCIIなので(そして私はそれを変更したくありません)それはそうするでしょう:
def encode_for_logging(c、encoding = 'ascii'): isinstance(c、basestring): c.encode(encoding、 'replace')を返します。 ] Elif isinstance(c、Iterable):cのvに対する c_ = [] : c_.append(encode_for_logging(v、encoding)) return c _ else: encode_for_logging(unicode(c))を返します`
非ASCII文字(値が128を超えるバイト)を含むURLで、同じエラーが発生しました
url = url.decode('utf8').encode('utf-8')
注:utf-8、utf8は単なるエイリアスです。 「utf8」または「utf-8」のみを使用しても同じように機能します
私の場合、Python 2.7で私のために働いたので、この割り当てがstr
内部表現の「何か」を変更したと思います。つまり、 url
そして最後に文字列をtf-8str
に入れ、すべての魔法を適切な場所に配置します。 PythonのUnicodeは私にとって黒魔術です。役に立つことを願って
同じエラーが発生し、これは私のエラーを解決しました。ありがとうございます。ユニコード処理が異なるpython 2とpython 3は、ピクルスファイルをロードするのに非常に互換性がありません。そのため、python pickleのエンコーディング引数を使用してください。私のファイルがもともとpython 2.xバージョンで保存されていた間に私が私のpython 3.7からピクルス化されたデータを開こうとしていたとき私は私が同じような問題を解決するのを助けました。 https://blog.modest-destiny.com/posts/python-2-and-3-compatible-pickle-save-and-load/ 私は自分のスクリプトでload_pickle関数をコピーし、load_pickle(pickle_file)と呼びます。 )このように私のinput_dataをロードしながら:
input_data = load_pickle("my_dataset.pkl")
Load_pickle関数はここにあります:
def load_pickle(pickle_file):
try:
with open(pickle_file, 'rb') as f:
pickle_data = pickle.load(f)
except UnicodeDecodeError as e:
with open(pickle_file, 'rb') as f:
pickle_data = pickle.load(f, encoding='latin1')
except Exception as e:
print('Unable to load data ', pickle_file, ':', e)
raise
return pickle_data
これは私のために働いた:
file = open('docs/my_messy_doc.pdf', 'rb')
これが私の解決策です。エンコーディングを追加するだけです。 with open(file, encoding='utf8') as f
そして、手袋ファイルを読むのは長い時間がかかるので、私は手袋ファイルをでたらめなファイルにすることを勧めます。あなたが埋め込み重みを読んだとき、それはあなたの時間を節約するでしょう。
import numpy as np
from tqdm import tqdm
def load_glove(file):
"""Loads GloVe vectors in numpy array.
Args:
file (str): a path to a glove file.
Return:
dict: a dict of numpy arrays.
"""
embeddings_index = {}
with open(file, encoding='utf8') as f:
for i, line in tqdm(enumerate(f)):
values = line.split()
Word = ''.join(values[:-300])
coefs = np.asarray(values[-300:], dtype='float32')
embeddings_index[Word] = coefs
return embeddings_index
# EMBEDDING_PATH = '../embedding_weights/glove.840B.300d.txt'
EMBEDDING_PATH = 'glove.840B.300d.txt'
embeddings = load_glove(EMBEDDING_PATH)
np.save('glove_embeddings.npy', embeddings)
要旨リンク: https://Gist.github.com/BrambleXu/634a844cdd3cd04bb2e3ba3c83aef227
#encoding = utf-8 をPythonファイルの先頭に指定してください。問題が解決するはずです。
Ubuntuインストールのオペレーティングシステムレベルでこれを解決するには、以下を確認してください。
$ locale charmap
あなたが取得する場合
locale: Cannot set LC_CTYPE to default locale: No such file or directory
の代わりに
UTF-8
それからLC_CTYPE
とLC_ALL
を次のように設定します。
$ export LC_ALL="en_US.UTF-8"
$ export LC_CTYPE="en_US.UTF-8"