web-dev-qa-db-ja.com

Pythonで文字列でUnicodeを宣言するのはなぜですか?

私はまだpythonを学んでいますが、疑問があります:

python 2.6.xでは、通常、このようにファイルヘッダーでエンコードを宣言します( PEP 026 のように)

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

その後、私のストリングはいつものように書かれます:

a = "A normal string without declared Unicode"

しかし、pythonプロジェクトコードが表示されるたびに、エンコードはヘッダーで宣言されません。代わりに、次のようにすべての文字列で宣言されます。

a = u"A string with declared Unicode"

違いは何ですか?これの目的は何ですか? Python 2.6.xがデフォルトでASCIIエンコーディングを設定することは知っていますが、ヘッダー宣言によってオーバーライドできるので、文字列ごとの宣言のポイントは何ですか?

補遺:ファイルエンコーディングと文字列エンコーディングを混在させているようです。それを説明してくれてありがとう:)

119
Oscar Carballal

他の人が述べたように、それらは2つの異なるものです。

# -*- coding: utf-8 -*-を指定すると、Pythonに保存したソースファイルはutf-8であることがわかります。 Python 2のデフォルトはASCIIです(Python 3の場合はutf-8です)。これは、インタープリターがファイル内の文字を読み取る方法に影響するだけです。

一般的に、エンコーディングが何であっても、高いユニコード文字をファイルに埋め込むことはおそらく最良のアイデアではありません。どちらのエンコーディングでも機能する文字列Unicodeエスケープを使用できます。


u'This is a string'のように、前にuを含む文字列を宣言すると、Pythonコンパイラに文字列バイトではなくユニコードです。これは、インタプリタによってほとんど透過的に処理されます。最も明らかな違いは、文字列にUnicode文字を埋め込むことができることです(つまり、u'\u2665'は現在有効です)。 from __future__ import unicode_literalsを使用して、デフォルトにすることができます。

これはPython 2にのみ適用されます。 Python 3ではデフォルトはUnicodeであり、bを前に指定する必要があります(b'These are bytes'など、バイトシーケンスを宣言するには)。

160
Chris B.

他の人が言ったように、# coding:はソースファイルが保存されるエンコーディングを指定します。これを説明するための例をいくつか示します。

cp437(私のコンソールエンコーディング)としてディスクに保存されているが、エンコーディングは宣言されていないファイル

b = 'über'
u = u'über'
print b,repr(b)
print u,repr(u)

出力:

  File "C:\ex.py", line 1
SyntaxError: Non-ASCII character '\x81' in file C:\ex.py on line 1, but no
encoding declared; see http://www.python.org/peps/pep-0263.html for details

# coding: cp437が追加されたファイルの出力:

über '\x81ber'
über u'\xfcber'

最初、Pythonはエンコードを知らず、非ASCII文字について不満を言いました。エンコードがわかると、バイト文字列は実際にディスク上にあるバイトを取得しました。 Unicode文字列のPythonは\ x81を読み取り、cp437でüであることを認識し、それをüのUnicodeコードポイントにデコードしました。 U + 00FC。バイト文字列が出力されると、Pythonは16進値81を直接コンソールに送信しました。 Unicode文字列が出力されると、Pythonはcp437としてコンソールエンコーディングを正しく検出し、Unicode üüのcp437値に変換しました。

TF-8で宣言および保存されたファイルで何が起こるか

├╝ber '\xc3\xbcber'
über u'\xfcber'

UTF-8では、üは16進バイトC3 BCとしてエンコードされるため、バイト文字列にはこれらのバイトが含まれますが、Unicode文字列は最初の例と同じです。 Pythonは2バイトを読み取り、正しくデコードしました。 Pythonは、バイト文字列を誤って印刷しました。これは、üを表す2つのUTF-8バイトをcp437コンソールに直接送信したためです。

ここでは、ファイルはcp437として宣言されていますが、UTF-8で保存されています:

├╝ber '\xc3\xbcber'
├╝ber u'\u251c\u255dber'

バイト文字列は依然としてディスク上のバイト(UTF-8 hex bytes C3 BC)を取得しましたが、単一のUTF-8エンコード文字ではなく2つのcp437文字として解釈しました。これらの2つの文字がUnicodeコードポイントに変換され、すべてが正しく印刷されません。

22
Mark Tolonen

それは文字列の形式を設定しません。ファイルの形式を設定します。そのヘッダーがあっても、"hello"はUnicode文字列ではなくバイト文字列です。 Unicodeにするには、u"hello"をどこでも使用する必要があります。ヘッダーは、.pyファイルを読み取るときに使用する形式のヒントにすぎません。

10
icktoofay

ヘッダー定義は、実行時の結果の文字列ではなく、コード自体のエンコードを定義することです。

utf-8ヘッダー定義なしでpythonスクリプトにlikeのような非ASCII文字を入力すると、警告がスローされます error

7
ebt