10 ответов:
в Python 3 все строки являются последовательностями символов Юникода. Там есть
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, а bytestring может содержать ASCII, кодированный Unicode или даже нетекстовые данные.
просто делать
type(s)одно скажу
unicode, другой скажетstr.вы можете обрабатывать их отдельно с помощью
isinstance, например,if isinstance(s, str): print 's is a string object' elif isinstance(s, unicode): print 's is a unicode object'или вы хотите сказать, что у вас есть
str, и вы пытаетесь выяснить, если он закодирован с помощьюASCIIилиUTF-8или что-то еще?в таком случае, попробуйте это:
s.decode('ascii')если он вызывает исключение, строка не является 100% ASCII.
в python 3.X все строки представляют собой последовательности символов Unicode. и выполнение проверки isinstance для str (что означает строку unicode по умолчанию) должно быть достаточным.
isinstance(x, str)что касается python 2.икс, Большинство людей, похоже, используют оператор if, который имеет две проверки. для УЛ и для Юникода.
Если вы хотите проверить, есть ли у вас "строковый" объект с одним оператором, вы можете сделать следующее:
isinstance(x, basestring)
Unicode - это не кодировка-цитирую Кумара Макмиллана:
Если ASCII, UTF-8 и другие байтовые строки являются "текстовыми" ...
...тогда Unicode - это "text-ness";
это абстрактная форма текста
почитайте Макмиллана Unicode В Python, Полностью Демистифицированный поговорите с PyCon 2008, это объясняет вещи намного лучше, чем большинство связанных ответов на переполнение стека.
если ваш код должен быть совместим с и Python 2 и Python 3, Вы не можете напрямую использовать такие вещи, как
isinstance(s,bytes)илиisinstance(s,unicode)не оборачивая их ни в try / except, ни в тест версии 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)это unpythonic, и большую часть времени там, наверное, лучший способ.
использование:
import six if isinstance(obj, six. text_type)внутри шести библиотек он представляет собой:
if PY3: string_types = str, else: string_types = basestring,
обратите внимание, что на Python 3, это не очень честно сказать:
strs являются UTFx для любого x (например. В utf8)
strс юникодом
strs-упорядоченные коллекции символов Юникодав Python
strтип - это (обычно) последовательность кодовых точек Юникода, некоторые из которых соответствуют символам.
даже на 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используется тот же метод для их различения.
вы могли бы использовать Универсальный Детектор Кодирования, но имейте в виду, что это просто даст вам лучшее предположение, а не фактическое кодирование, потому что невозможно узнать кодировку строки "abc", например. Вам нужно будет получить информацию о кодировке в другом месте, например, протокол HTTP использует заголовок типа контента для этого.
Это может помочь кому-то еще, я начал тестирование для строкового типа переменной 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') 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
Comments