回答:
Python 3では、すべての文字列はUnicode文字のシーケンスです。bytes
生のバイトを保持するタイプがあります。
Python 2では、文字列はtype str
またはTypeの場合がありunicode
ます。あなたは次のようなコードを使用してどちらかを知ることができます:
def whatisthis(s):
if isinstance(s, str):
print "ordinary string"
elif isinstance(s, unicode):
print "unicode string"
else:
print "not a string"
これは「UnicodeまたはASCII」を区別しません。Pythonの型を区別するだけです。Unicode文字列は、ASCII範囲の純粋な文字で構成される場合があり、バイト文字列は、ASCII、エンコードされたUnicode、または非テキストデータを含む場合があります。
type
またはを使用できますisinstance
。
Python 2の場合:
>>> type(u'abc') # Python 2 unicode string literal
<type 'unicode'>
>>> type('abc') # Python 2 byte string literal
<type 'str'>
Python 2ではstr
、バイトのシーケンスです。Pythonはそのエンコーディングが何であるかを知りません。unicode
タイプは、ストアテキストに安全な方法です。これについてもっと理解したい場合は、http://farmdev.com/talks/unicode/をお勧めします。
Python 3の場合:
>>> type('abc') # Python 3 unicode string literal
<class 'str'>
>>> type(b'abc') # Python 3 byte string literal
<class 'bytes'>
Python 3では、str
Python 2と同様にunicode
、テキストを格納するために使用されます。何と呼ばれていたstr
のPython 2には、呼び出されたbytes
Pythonの3に。
あなたが呼び出すことができますdecode
。UnicodeDecodeError例外が発生した場合、それは無効でした。
>>> u_umlaut = b'\xc3\x9c' # UTF-8 representation of the letter 'Ü'
>>> u_umlaut.decode('utf-8')
u'\xdc'
>>> u_umlaut.decode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
unicode(s, "ascii")
何かしなければならないようです
str(s, "ascii")
Python 3.xでは、すべての文字列はUnicode文字のシーケンスです。また、str(デフォルトではUnicode文字列を意味します)のisinstanceチェックを実行するだけで十分です。
isinstance(x, str)
Python 2.xに関しては、ほとんどの人が2つのチェックを持つifステートメントを使用しているようです。1つはstr用、もう1つはUnicode用です。
「string-like」オブジェクトがあるかどうかをすべて1つのステートメントで確認したい場合は、次のようにします。
isinstance(x, basestring)
isinstance(u"x",basestring)
が返されますTrue
。
Unicodeはエンコーディングではありません-Kumar McMillanを引用すると:
ASCII、UTF-8、およびその他のバイト文字列が「テキスト」の場合...
...そしてUnicodeは「テキストらしさ」です。
それはテキストの抽象的な形です
McMillanのUnicode In Python、 PyCon 2008の完全に謎解きの講演を読んで、Stack Overflowの関連するほとんどの回答よりもはるかに優れた点について説明しています。
あなたのコードのニーズはと互換性のある場合は、両方のPython 2とPython 3、あなたは直接のようなものを使用することはできませんisinstance(s,bytes)
やがisinstance(s,unicode)
あるため、以外やPythonのバージョンのテスト/どちらかの試みでそれらをラップすることなく、bytes
Pythonの2に定義されていないとunicode
のPython 3で定義されていません。
いくつかの醜い回避策があります。非常に醜いのは、型自体を比較するのではなく、型の名前を比較することです。次に例を示します。
# convert bytes (python 3) or unicode (python 2) to str
if str(type(s)) == "<class 'bytes'>":
# only possible in Python 3
s = s.decode('ascii') # or s = str(s)[2:-1]
elif str(type(s)) == "<type 'unicode'>":
# only possible in Python 2
s = str(s)
間違いなく少し醜い回避策は、Pythonのバージョン番号を確認することです。例:
if sys.version_info >= (3,0,0):
# for Python 3
if isinstance(s, bytes):
s = s.decode('ascii') # or s = str(s)[2:-1]
else:
# for Python 2
if isinstance(s, unicode):
s = str(s)
これらはどちらも非Pythonicであり、ほとんどの場合、おそらくより良い方法があります。
six
、そしてテストに対するsix.binary_type
とsix.text_type
使用する:
import six
if isinstance(obj, six.text_type)
6つのライブラリ内では、次のように表されます。
if PY3:
string_types = str,
else:
string_types = basestring,
if isinstance(obj, six.text_type)
。しかし、これは正しい答えです。
Python 3では、次のいずれかを言うのは実際には公平ではないことに注意してください。
str
sは任意のxのUTFx(例:UTF8)
str
sはUnicodeです
str
sはUnicode文字の順序付けられたコレクションです
Pythonのstr
タイプは(通常)Unicodeコードポイントのシーケンスであり、その一部は文字にマップされます。
Python 3であっても、想像するほど簡単にこの質問に答えることはできません。
ASCII互換文字列をテストする明らかな方法は、エンコードを試行することです。
"Hello there!".encode("ascii")
#>>> b'Hello there!'
"Hello there... ☃!".encode("ascii")
#>>> Traceback (most recent call last):
#>>> File "", line 4, in <module>
#>>> UnicodeEncodeError: 'ascii' codec can't encode character '\u2603' in position 15: ordinal not in range(128)
エラーはケースを区別します。
Python 3では、無効なUnicodeコードポイントを含む文字列もいくつかあります。
"Hello there!".encode("utf8")
#>>> b'Hello there!'
"\udcc3".encode("utf8")
#>>> Traceback (most recent call last):
#>>> File "", line 19, in <module>
#>>> UnicodeEncodeError: 'utf-8' codec can't encode character '\udcc3' in position 0: surrogates not allowed
それらを区別するために同じ方法が使用されます。
これは他の人に役立つかもしれません。変数sの文字列型のテストを開始しましたが、私のアプリケーションでは、単にsをutf-8として返す方が理にかなっています。次に、return_utfを呼び出すプロセスは、何を処理しているかを認識し、文字列を適切に処理できます。コードは原始的ではありませんが、バージョンテストや6つのインポートを行わないPythonバージョンに依存しないようにするつもりです。他の人を助けるために、以下のサンプルコードを改善してコメントしてください。
def return_utf(s):
if isinstance(s, str):
return s.encode('utf-8')
if isinstance(s, (int, float, complex)):
return str(s).encode('utf-8')
try:
return s.encode('utf-8')
except TypeError:
try:
return str(s).encode('utf-8')
except AttributeError:
return s
except AttributeError:
return s
return s # assume it was already utf-8
Universal Encoding Detectorを使用することもできますが、実際のエンコーディングではなく、推測に過ぎないことに注意してください。たとえば、文字列 "abc"のエンコーディングを知ることは不可能です。他の場所でエンコーディング情報を取得する必要があります。たとえば、HTTPプロトコルはそのためにContent-Typeヘッダーを使用します。
py2 / py3の互換性のために、単に使用します
import six
if isinstance(obj, six.text_type)