web-dev-qa-db-ja.com

(Unicodeエラー) 'unicodeescape'コーデックはバイトをデコードできません-'\ u'を含む文字列

Python 2.6のコードを記述しますが、Python 3を念頭に置いて、

from __future__ import unicode_literals

一部のモジュールの上部。つまり、将来トラブルを回避するためにトラブルを求めていますが、ここでは重要な知識が不足している可能性があります。ファイルパスを表す文字列を渡して、オブジェクトを簡単にインスタンス化できるようにしたい

MyObject('H:\unittests')

に Python 2.6、これはうまく機能します。'\u..'で始まるディレクトリでも、二重のバックスラッシュや生の文字列を使用する必要はありません。 __init__メソッドでは、\\\\a\b\f\n\r\tのみ)のように、特殊文字の前にあるものも含めて、すべての単一の\vが '\x'として解釈されることを確認します。また、(ローカル)エンコーディングを使用して、指定された文字列をUnicodeにデコードすると、期待どおりに機能します。

準備中 Python 3.x、エディターで実際の問題をシミュレート(Python 2.6のクリーンコンソールから開始))すると、次のようになります。

>>> '\u'
'\\u'
>>> r'\u'
'\\u'

(ここまでOK:'\u'はコンソールによってローカルエンコーディングを使用してエンコードされます)

>>> from __future__ import unicode_literals
>>> '\u'
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-1: end of string in escape sequence

つまり、(Unicode)文字列はUnicodeとして解釈されず、ローカルエンコーディングで自動的にデコードされることもありません。生の文字列でもそうです:

>>> r'\u'
SyntaxError: (unicode error) 'rawunicodeescape' codec can't decode bytes in position 0-1: truncated \uXXXX

u'\u'についても同じです。

>>> u'\u'
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-1: end of string in escape sequence

また、isinstance(str(''), unicode)Trueを返すことを期待します(そうではありません)。これは、unicode_literalsをインポートすると、すべての文字列型がユニコードになるためです。 (編集:)in Python 3、すべての文字列はUnicode文字のシーケンス であるため、str(''))がそのようなUnicode文字列を返し、type(str(''))は、<type 'unicode'><type 'str'>の両方になります(すべての文字列がユニコードであるため)が、<type 'unicode'> is not <type 'str'>であることも理解してください。

ご質問

  • \u」を含む文字列を渡すにはどうすればよいですか? (「\\u」を書かずに)
  • from __future__ import unicode_literalsは本当にすべてのPython 3.関連するユニコードの変更を実装するので、完全なPython 3文字列環境を取得できますか?

編集:Python 3、 <type 'str'>はUnicodeオブジェクトです そして、<type 'unicode'>は単に存在しません。私の場合、Python 2(.6)これはPython 3.で機能します。 import unicode_literalsを実行すると、文字列が<type 'unicode'>であるかどうかを確認できません。

  • unicodeは名前空間の一部ではないと思います
  • unicodeが名前空間の一部である場合、<type 'str'>のリテラルは、同じモジュールで作成されたときでもユニコードです
  • type(mystring)は、Unicodeリテラルに対してPython 3の場合、常に<type 'str'>を返します

私のモジュールは、上部の# coding: UTF-8コメントによって 'utf-8'でエンコードされていましたが、locale.getdefaultlocale()[1]は 'cp1252'を返します。したがって、コンソールからMyObject('çça')を呼び出すと、Python 2で 'cp1252'としてエンコードされ、MyObject('çça')からPython 3では、エンコードされませんが、Unicodeリテラルです。

編集:

私はu(またはそのことについてはx)の前に '\'を使用しないことを許可されることについての希望をあきらめました。また、unicode_literalsのインポートの制限についても理解しています。ただし、モジュールからコンソールに文字列を渡したり、エンコードを変えて文字列を渡したり、さらにはunicode_literalsをインポートするかどうか、およびPython 2 vs Python 3で、実際のテストで概要を作成したいと思ったので、以下の表をご覧ください。 enter image description here

言い換えると、type(str(''))はPython 3では<type 'str'>を返さず、<class 'str'>を返します。Python 2の問題はすべて回避されているようです。

25
Remi

申し訳ありませんが、from __future__ import unicode_literalsが行うことは、文字列型ではなく、すべての文字列リテラルをUnicode型にすることです。あれは:

>>> type('')
<type 'str'>
>>> from __future__ import unicode_literals
>>> type('')
<type 'unicode'>

ただし、strunicodeはまだ異なる型であり、以前と同じように動作します。

>>> type(str(''))
<type 'str'>

常にstrタイプです。

r'\u'の問題については、unicode_literalsなしのru '\ u'と同等であるため、仕様によるものです。ドキュメントから:

'r'または 'R'プレフィックスを 'u'または 'U'プレフィックスと組み合わせて使用​​すると、\ uXXXXおよび\ UXXXXXXXXエスケープシーケンスが処理され、他のすべてのバックスラッシュは文字列に残ります。

おそらく、字句解析器がpython2シリーズで機能した方法からです。 python3では、あなた(そして私)が期待するように動作します。

バックスラッシュを2回入力すると、\uは解釈されませんが、2つのバックスラッシュが表示されます。

バックスラッシュは、先行するバックスラッシュでエスケープできます。ただし、どちらも文字列に残ります

>>> ur'\\u'
u'\\\\u'

だから私見、あなたは2つの簡単なオプションがあります:

  • 生の文字列を使用せず、バックスラッシュをエスケープします(python3と互換性があります):

    'H:\\unittests'

  • あまりにも賢く、Unicodeコードポイントを利用してください(not python3と互換性があります):

    r'H:\u005cunittests'

18
rodrigo

私にとって、この問題は最新ではないバージョンに関連し、この場合はnumpy

修正するには:

conda install -f numpy
0
blue-sky