В Python 3 все строки являются последовательностями символов Unicode. Существует bytesтип, который содержит необработанные байты.
В Python 2 строка может иметь тип strили тип 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 или даже нетекстовые данные.
В Python 2 strэто просто последовательность байтов. Python не знает, какова его кодировка. unicodeТипа является более безопасным способом для хранения текста. Если вы хотите понять это больше, я рекомендую http://farmdev.com/talks/unicode/ .
В Python 3 strпохож на Python 2 unicodeи используется для хранения текста. То, что было названо strв Python 2, называется bytesв Python 3.
Как определить, действительна ли байтовая строка utf-8 или ascii?
Вы можете позвонить 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)
Просто для справки других людей - str.decode не существует в python 3. Похоже, что вы должны unicode(s, "ascii")или что-то
Shadow
3
Извините, я имел в видуstr(s, "ascii")
Shadow
1
Это не совсем верно для Python 3
ProsperousHeart
2
@ProsperousHeart Обновлено, чтобы охватить Python 3. И попытаться объяснить разницу между строками байтов и юникодом.
Микель
44
В Python 3.x все строки являются последовательностями символов Unicode. и достаточно выполнить проверку isinstance для str (что по умолчанию означает строку unicode).
isinstance(x, str)
Что касается python 2.x, большинство людей, похоже, используют оператор if, который имеет две проверки. один для ул и один для юникода.
Если вы хотите проверить, есть ли у вас «строковый» объект с одним оператором, вы можете сделать следующее:
Это неверно В Python 2.7 isinstance(u"x",basestring)возвращается True.
PythonNut
11
@PythonNut: я считаю, что это было главное. Использование isinstance (x, basestring) достаточно для замены вышеупомянутых двойных тестов.
KQ.
5
Это полезно во многих случаях, но, очевидно, не то, что имел в виду спрашивающий.
mhsmith
3
Это - ответ на вопрос. Все остальные не поняли, что сказал OP, и дали общие ответы о проверке типов в Python.
fiatjaf
1
Не отвечает на вопрос ОП. Название вопроса (в одиночку) МОЖЕТ быть истолковано так, чтобы этот ответ был правильным. Тем не менее, ОП конкретно говорит «выяснить, какой» в описании вопроса, и этот ответ не касается этого.
MD004
31
Юникод не является кодировкой - цитирую Кумара Макмиллана:
Если ASCII, UTF-8 и другие байтовые строки являются «текстовыми» ...
Эти слайды, вероятно, являются лучшим введением в Unicode, с которым я когда-либо встречался
Джонни
23
Если ваш код должен быть совместим как с Python 2, так и с Python 3, вы не можете напрямую использовать такие вещи, как isinstance(s,bytes)или isinstance(s,unicode)без их обтекания, либо в try / exception, либо в тесте версии python, потому что bytesне определено в Python 2 и unicodeне определено в Python 3 ,
Есть некоторые уродливые обходные пути. Чрезвычайно уродливо сравнивать имя типа, а не сравнивать сам тип. Вот пример:
# convert bytes (python 3) or unicode (python 2) to strif 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 3if isinstance(s, bytes):
s = s.decode('ascii')# or s = str(s)[2:-1]else:# for Python 2if isinstance(s, unicode):
s = str(s)
Они оба не пифоничны, и в большинстве случаев, вероятно, есть лучший способ.
Лучший способ это возможно использование sixи испытание против six.binary_typeиsix.text_type
Ian Клелланд
1
Вы можете использовать тип (ы) .__ name__ для проверки имен типов.
Пауло Фрейтас
Я не совсем уверен в случае использования для этого бита кода, если только нет логической ошибки. Я думаю, что должно быть "не" в коде Python 2. В противном случае вы конвертируете все в строки Unicode для Python 3 и наоборот для Python 2!
oligofren
Да, олигофрен, это то, что он делает. Стандартными внутренними строками являются Unicode в Python 3 и ASCII в Python 2. Поэтому фрагменты кода преобразуют текст в стандартный тип внутренней строки (будь то Unicode или ASCII).
Дейв Бертон,
12
использовать:
import six
if isinstance(obj, six.text_type)
внутри шести библиотек она представлена в виде:
if PY3:
string_types = str,else:
string_types = basestring,
так и должно быть if isinstance(obj, six.text_type) . Но да, это правильный ответ.
Карантан
Не отвечает на вопрос ОП. Название вопроса (в одиночку) МОЖЕТ быть истолковано так, чтобы этот ответ был правильным. Тем не менее, ОП конкретно говорит «выяснить, какой» в описании вопроса, и этот ответ не касается этого.
MD004
4
Обратите внимание, что в Python 3 не совсем справедливо сказать следующее:
strs - это UTFx для любого x (например, UTF8)
strUnicode
strs - упорядоченные коллекции символов Unicode
strТип Python - это (обычно) последовательность кодовых точек 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, затем знает, с чем имеет дело, и может соответствующим образом обработать строку. Код не является первозданным, но я намерен сделать его независимым от версии 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')exceptTypeError:try:return str(s).encode('utf-8')exceptAttributeError:return s
exceptAttributeError:return s
return s # assume it was already utf-8
Вы, мой друг, заслуживаете правильного ответа! Я использую Python 3, и у меня все еще были проблемы, пока я не нашел это сокровище!
мрин
2
Вы можете использовать Universal Encoding Detector , но имейте в виду, что он просто даст вам лучшее предположение, а не фактическую кодировку, потому что невозможно узнать кодировку строки «abc», например. Вам нужно будет получить информацию о кодировке в другом месте, например, протокол HTTP для этого использует заголовок Content-Type.
Один простой подход - проверить, unicodeявляется ли встроенная функция. Если это так, вы находитесь в Python 2, и ваша строка будет строкой. Чтобы убедиться, что все в unicodeодном можно сделать:
import builtins
i ='cats'if'unicode'in dir(builtins):# True in python 2, False in 3
i = unicode(i)
{UnicodeDecodeError} 'ascii' codec can't decode byte 0xc2
Ответы:
В Python 3 все строки являются последовательностями символов Unicode. Существует
bytes
тип, который содержит необработанные байты.В Python 2 строка может иметь тип
str
или типunicode
. Вы можете сказать, что с помощью кода примерно так:Это не различает «Unicode или ASCII»; он различает только типы Python. Строка Unicode может состоять из чисто символов в диапазоне ASCII, а строка байтов может содержать ASCII, кодированный Unicode или даже нетекстовые данные.
источник
Как определить, является ли объект строкой Unicode или строкой байтов
Вы можете использовать
type
илиisinstance
.В Python 2:
В Python 2
str
это просто последовательность байтов. Python не знает, какова его кодировка.unicode
Типа является более безопасным способом для хранения текста. Если вы хотите понять это больше, я рекомендую http://farmdev.com/talks/unicode/ .В Python 3:
В Python 3
str
похож на Python 2unicode
и используется для хранения текста. То, что было названоstr
в Python 2, называетсяbytes
в Python 3.Как определить, действительна ли байтовая строка utf-8 или ascii?
Вы можете позвонить
decode
. Если оно вызывает исключение UnicodeDecodeError, оно недопустимо.источник
unicode(s, "ascii")
или что-тоstr(s, "ascii")
В Python 3.x все строки являются последовательностями символов Unicode. и достаточно выполнить проверку isinstance для str (что по умолчанию означает строку unicode).
Что касается python 2.x, большинство людей, похоже, используют оператор if, который имеет две проверки. один для ул и один для юникода.
Если вы хотите проверить, есть ли у вас «строковый» объект с одним оператором, вы можете сделать следующее:
источник
isinstance(u"x",basestring)
возвращаетсяTrue
.Юникод не является кодировкой - цитирую Кумара Макмиллана:
Прочитайте Юникод Макмиллана. В Python, «Полностью демистифицированный доклад» из PyCon 2008, он объясняет вещи намного лучше, чем большинство связанных ответов о переполнении стека.
источник
Если ваш код должен быть совместим как с Python 2, так и с Python 3, вы не можете напрямую использовать такие вещи, как
isinstance(s,bytes)
илиisinstance(s,unicode)
без их обтекания, либо в try / exception, либо в тесте версии python, потому чтоbytes
не определено в Python 2 иunicode
не определено в Python 3 ,Есть некоторые уродливые обходные пути. Чрезвычайно уродливо сравнивать имя типа, а не сравнивать сам тип. Вот пример:
Возможно, немного менее уродливый обходной путь - проверить номер версии Python, например:
Они оба не пифоничны, и в большинстве случаев, вероятно, есть лучший способ.
источник
six
и испытание противsix.binary_type
иsix.text_type
использовать:
внутри шести библиотек она представлена в виде:
источник
if isinstance(obj, six.text_type)
. Но да, это правильный ответ.Обратите внимание, что в Python 3 не совсем справедливо сказать следующее:
str
s - это UTFx для любого x (например, UTF8)str
Unicodestr
s - упорядоченные коллекции символов Unicodestr
Тип Python - это (обычно) последовательность кодовых точек Unicode, некоторые из которых отображаются на символы.Даже на Python 3 ответить на этот вопрос не так просто, как вы можете себе представить.
Очевидным способом проверки ASCII-совместимых строк является попытка кодирования:
Ошибка различает случаи.
В Python 3 есть даже некоторые строки, которые содержат недопустимые кодовые точки Unicode:
Используется тот же метод, чтобы различать их.
источник
Это может помочь кому-то еще, я начал тестировать строковый тип переменной s, но для моего приложения было больше смысла просто возвращать s как utf-8. Процесс, вызывающий return_utf, затем знает, с чем имеет дело, и может соответствующим образом обработать строку. Код не является первозданным, но я намерен сделать его независимым от версии Python без проверки версии или импорта шести. Пожалуйста, прокомментируйте улучшения кода ниже, чтобы помочь другим людям.
источник
Вы можете использовать Universal Encoding Detector , но имейте в виду, что он просто даст вам лучшее предположение, а не фактическую кодировку, потому что невозможно узнать кодировку строки «abc», например. Вам нужно будет получить информацию о кодировке в другом месте, например, протокол HTTP для этого использует заголовок Content-Type.
источник
Для совместимости с py2 / py3 просто используйте
import six if isinstance(obj, six.text_type)
источник
Один простой подход - проверить,
unicode
является ли встроенная функция. Если это так, вы находитесь в Python 2, и ваша строка будет строкой. Чтобы убедиться, что все вunicode
одном можно сделать:источник