Как проверить, является ли переменная строкой с Python 2 и 3 совместимостью

Я знаю, что я могу использовать: isinstance(x, str) в python-3.x, но мне нужно проверить, является ли что-то строкой в ​​python-2.x. Будет isinstance(x, str) работать как положено в python-2.x? Или мне нужно будет проверить версию и использовать isinstance(x, basestr)?

В частности, в python-2.x:

>>>isinstance(u"test", str)
False

и python-3.x не имеет u"foo"

8 ответов

Решение

Если вы пишете 2.x-and-3.x-совместимый код, вы, вероятно, захотите использовать шесть:

from six import string_types
isinstance(s, string_types)

Самый краткий подход, который я нашел, не полагаясь на пакеты вроде шести, это:

try:
  basestring
except NameError:
  basestring = str

затем, при условии, что вы проверяли строки в Python 2 самым общим способом,

isinstance(s, basestring)

теперь также будет работать для Python 3+.

Как насчет этого, работает во всех случаях?

isinstance(x, ("".__class__, u"".__class__))

Это ответ @Lev Левицкого, переписанный немного.

try:
    isinstance("", basestring)
    def isstr(s):
        return isinstance(s, basestring)
except NameError:
    def isstr(s):
        return isinstance(s, str)

try/except test выполняется один раз, а затем определяет функцию, которая всегда работает и работает максимально быстро.

РЕДАКТИРОВАТЬ: На самом деле, нам даже не нужно звонить isinstance(); нам просто нужно оценить basestring и посмотрим, получим ли мы NameError:

try:
    basestring  # attempt to evaluate basestring
    def isstr(s):
        return isinstance(s, basestring)
except NameError:
    def isstr(s):
        return isinstance(s, str)

Я думаю, что легче следовать с призывом isinstance(), хоть.

future Библиотека добавляет (в Python 2) совместимые имена, чтобы вы могли продолжить писать Python 3. Вы можете просто сделать следующее:

from builtins import str
isinstance(x, str) 

Чтобы установить его, просто выполните pip install future,

Как предостережение, это только поддержка python>=2.6, >=3.3, но это более современно, чем six, который рекомендуется только при использовании python 2.5

Вы можете получить класс объекта, вызвав object.__class__, чтобы проверить, является ли объект строковым типом по умолчанию:

    isinstance(object,"".__class__)

И Вы можете поместить следующее в верхней части своего кода, чтобы строки, заключенные в кавычки, находились в юникоде в python 2:

    from __future__ import unicode_literals

Может быть, использовать обходной путь, как

def isstr(s):
    try:
        return isinstance(s, basestring)
    except NameError:
        return isinstance(s, str)

Быть осторожен! В Python 2str а также bytesпо сути одинаковы. Это может вызвать ошибку, если вы пытаетесь различить их.

>>> size = 5    
>>> byte_arr = bytes(size)
>>> isinstance(byte_arr, bytes)
True
>>> isinstance(byte_arr, str)
True

Вы можете попробовать это в начале вашего кода:

from __future__ import print_function
import sys
if sys.version[0] == "2":
    py3 = False
else:
    py3 = True
if py3: 
    basstring = str
else:
    basstring = basestring

и позже в коде:

anystring = "test"
# anystring = 1
if isinstance(anystring, basstring):
    print("This is a string")
else:
    print("No string")

Тип (строка) == стр

возвращает true, если это строка, и false, если нет

Другие вопросы по тегам