Как проверить, является ли тип переменной строковым?

766

Есть ли способ проверить, является ли тип переменной в Python string, как:

isinstance(x,int);

для целочисленных значений?

c_pleaseUpvote
источник
11
Обязательное чтение на isinstance, если вы изучаете python canonical.org/~kragen/isinstance .
Кит
см. stackoverflow.com/a/1979107/1145750
Гэри Гаух
Будьте осторожны с целыми числами с тех пор isinstance(True, int) is True.
Альберт Тугушев
isinstance(x,str)правильно в Python 3 (str является базовым типом).
MasterControlProgram

Ответы:

1139

В Python 2.x вы бы сделали

isinstance(s, basestring)

basestringэто абстрактный суперкласс из strи unicode. Его можно использовать для проверки того, является ли объект экземпляром strили unicode.


В Python 3.x правильный тест

isinstance(s, str)

bytesКласс не считается типом строки в Python 3.

Свен Марнах
источник
10
@ Ярин: Нет. Но это не имеет значения, потому что Python 3.x вовсе не предназначен для совместимости с Python 2.x.
Netcoder
2
Я обнаружил, что isinstance (s, str) работает с py27, протестировано на: Python 2.7.5 (по умолчанию, 25 августа 2013, 00:04:04) [GCC 4.2.1 Совместимый Apple LLVM 5.0 (clang-500.0.68)] на дарвина
kakyo
25
@kakyo: проблема в том, что он будет пропускать unicodeобъекты, которые также должны рассматриваться как строки. И тип, strи тип unicodeимеют общий базовый класс basestring, и это то, что вы хотите проверить.
Свен Марнач
7
@ Ярин, если вы переносите что-то с 2.x на 3.x, вы всегда можете назначить basestring = str.
Джек,
9
@AdamErickson Для совместимости с чем именно? Это не помогает для совместимости с Python 3, так как unicodeв Python 3 его нет. Моя рекомендация по совместимости между Python 2 и 3 - использовать библиотеку «шести». (Конкретно isintance(s, six.string_types)в этом случае)
Свен Марнах
222

Я знаю, что это старая тема, но, будучи первой, показанной в Google и учитывая, что я не нашел ни одного из ответов, удовлетворительных, я оставлю это здесь для дальнейшего использования:

six - это библиотека совместимости Python 2 и 3, которая уже охватывает эту проблему. Затем вы можете сделать что-то вроде этого:

import six

if isinstance(value, six.string_types):
    pass # It's a string !!

Проверяя код, вот что вы найдете:

import sys

PY3 = sys.version_info[0] == 3

if PY3:
    string_types = str,
else:
    string_types = basestring,
Андре Фрателли
источник
4
Например, для одной строки : value_is_string = isinstance(value, str if sys.version_info[0] >= 3 else basestring)где >=предполагается, что любой возможный Python 4+ сохраняет strкорневой класс для строк.
Пи Мариллион
65

В Python 3.x или Python 2.7.6

if type(x) == str:
Texom512
источник
10
Мне нравится элегантность "if type (x) in (str, unicode):", но я вижу, что PyLint помечает его как "unidiomatic".
eukras 22.12.15
16
Сравнение типов с ==явным образом не поощряется PEP8 и имеет несколько недостатков, которые также считаются «однотипными», например, он не обнаруживает экземпляры подклассов str, которые также должны рассматриваться как строки. Если вы действительно хотите точно проверить тип strи явно исключить подклассы, используйте type(x) is str.
Свен Марнач
17

ты можешь сделать:

var = 1
if type(var) == int:
   print('your variable is an integer')

или:

var2 = 'this is variable #2'
if type(var2) == str:
    print('your variable is a string')
else:
    print('your variable IS NOT a string')

надеюсь это поможет!

Ф. Тейлор
источник
11

Редактировать на основе лучшего ответа ниже. Пройдите около 3 ответов и узнайте о крутизне базовых строк.

Старый ответ: следите за строками Unicode, которые вы можете получить из нескольких мест, включая все вызовы COM в Windows.

if isinstance(target, str) or isinstance(target, unicode):
Уэйд Хэтлер
источник
1
Хороший улов. Я не знал о базовой цепочке. Упоминается о 3 сообщениях вниз и кажется лучшим ответом.
Уэйд Хэтлер
6
isinstance()также принимает кортеж в качестве второго аргумента. Так что даже если basestringбы не было, вы могли бы просто использовать isinstance(target, (str, unicode)).
Мартин Питерс
3
В python 3.5.1, unicodeкажется, не определены:NameError: name 'unicode' is not defined
Эрик Ху
11

поскольку basestringон не определен в Python3, этот маленький трюк может помочь сделать код совместимым:

try: # check whether python knows about 'basestring'
   basestring
except NameError: # no, it doesn't (it's Python3); use 'str' instead
   basestring=str

после этого вы можете запустить следующий тест на Python2 и Python3

isinstance(myvar, basestring)
umläute
источник
4
Или, если вы хотите поймать строки байтов тоже:basestring = (str, bytes)
Марк Рэнсом
10

Python 2/3, включая Юникод

from __future__ import unicode_literals
from builtins import str  #  pip install future
isinstance('asdf', str)   #  True
isinstance(u'asdf', str)  #  True

http://python-future.org/overview.html

crizCraig
источник
1
Большое спасибо! В Интернете есть десятки различных ответов, но единственное хорошее - это один. Первая строка делает type('foo')быть unicodeпо умолчанию в Python 2, а вторая один маркой strявляется экземпляром unicode. Thoses делает код действительным в Python 2 и 3. Еще раз спасибо!
Наранн
9

Также я хочу заметить, что если вы хотите проверить, является ли тип переменной конкретным видом, вы можете сравнить тип переменной с типом известного объекта.

Для строки вы можете использовать это

type(s) == type('')
Даниил Гранкин
источник
7
Это ужасный, ужасный способ проверки типов в python. Что если другой класс наследует от str? А как насчет строк Юникода, которые даже не наследуются strв 2.x? Используйте isinstance(s, basestring)в 2.x или isinstance(s, str)в 3.x.
Джек,
1
@ Джек, пожалуйста, прочитайте вопрос, а также обратите внимание, что я не пишу, что это лучший способ, просто другой способ.
Даниил Гранкин
9
Это плохая идея по 3 причинам: isinstance()учитывает подклассы (которые тоже являются строками, только специализированные), дополнительный type('')вызов избыточен, когда вы можете просто его использовать, strа типы являются одиночными, поэтому type(s) is strэто будет более эффективный тест.
Мартин Питерс
8

Здесь много хороших предложений от других, но я не вижу хорошего кроссплатформенного резюме. Следующее должно быть хорошим дополнением для любой программы Python:

def isstring(s):
    # if we use Python 3
    if (sys.version_info[0] >= 3):
        return isinstance(s, str)
    # we use Python 2
    return isinstance(s, basestring)

В этой функции мы используем, isinstance(object, classinfo)чтобы увидеть, является ли наш ввод strв Python 3 или basestringв Python 2.

duanev
источник
1
Это, вероятно, сломается в Python 4, рассмотрим >=хотя бы.
Thakis
2
быть чище, чтобы проверить наличие Six.string_types или six.text_type
daonb
@daonb, импортирующий весь модуль просто для того, чтобы выполнить однострочный тест, - это мышление, которое приводит к тому, что сумасшедшие деревья зависимостей и серьезное раздутие разрушают то, что должно быть чем-то коротким, маленьким и простым. Это, конечно, ваш звонок, но просто скажите, что ...
дуанев
@duanev, если вы беспокоитесь о совместимости с Python 2/3, лучше в любом случае использовать шесть в проекте. Шесть также является одним файлом, поэтому деревья зависимостей / раздувание здесь не проблема.
MoxieBall
7

Альтернативный способ для Python 2, без использования basestring:

isinstance(s, (str, unicode))

Но все еще не будет работать в Python 3, так unicodeкак он не определен (в Python 3).

yprez
источник
7

Так,

У вас есть много вариантов, чтобы проверить, является ли ваша переменная строковой или нет:

a = "my string"
type(a) == str # first 
a.__class__ == str # second
isinstance(a, str) # third
str(a) == a # forth
type(a) == type('') # fifth

Этот заказ для цели.

PatNowak
источник
5
a = '1000' # also tested for 'abc100', 'a100bc', '100abc'

isinstance(a, str) or isinstance(a, unicode)

возвращает True

type(a) in [str, unicode]

возвращает True

be_good_do_good
источник
Для Python 2.7.12 мне пришлось удалить кавычки: type (a) в [str, unicode]
Адам Эриксон,
4

Вот мой ответ для поддержки Python 2 и Python 3 вместе с этими требованиями:

  • Написано в коде Py3 с минимальным совместимым кодом Py2.
  • Удалить код Py2 Compat позже без сбоев. Т.е. стремиться только к удалению, без изменений в коде Py3.
  • Избегайте использования sixили аналогичного модуля Compat, так как они имеют тенденцию скрывать то, что пытаются достичь.
  • Перспектива для потенциального Py4.

import sys
PY2 = sys.version_info.major == 2

# Check if string (lenient for byte-strings on Py2):
isinstance('abc', basestring if PY2 else str)

# Check if strictly a string (unicode-string):
isinstance('abc', unicode if PY2 else str)

# Check if either string (unicode-string) or byte-string:
isinstance('abc', basestring if PY2 else (str, bytes))

# Check for byte-string (Py3 and Py2.7):
isinstance('abc', bytes)
Cas
источник
1

Если вы не хотите зависеть от внешних библиотек, это работает как для Python 2.7+, так и для Python 3 ( http://ideone.com/uB4Kdc ):

# your code goes here
s = ["test"];
#s = "test";
isString = False;

if(isinstance(s, str)):
    isString = True;
try:
    if(isinstance(s, basestring)):
        isString = True;
except NameError:
    pass;

if(isString):
    print("String");
else:
    print("Not String");
mPrinC
источник
1

Вы можете просто использовать функцию isinstance, чтобы убедиться, что входные данные имеют форматную строку или юникод . Приведенные ниже примеры помогут вам легко понять.

>>> isinstance('my string', str)
True
>>> isinstance(12, str)
False
>>> isinstance('my string', unicode)
False
>>> isinstance(u'my string',  unicode)
True
Хасан Мехмуд
источник
-3
s = '123'
issubclass(s.__class__, str)
Вадим Вадукса
источник
-6

Вот как я это делаю:

if type(x) == type(str()):
пользователь
источник
4
type(str())это очень окольный способ сказать str. Типы являются синглетонами, поэтому type(x) is strболее эффективны. isinstance()следует использовать вместо, если у вас нет очень веских причин игнорировать подклассы str.
Мартин Питерс
если тип (x) str:
shaurya Уппал
-7

Я видел:

hasattr(s, 'endswith') 
быстрый зуб
источник
-13
>>> thing = 'foo'
>>> type(thing).__name__ == 'str' or type(thing).__name__ == 'unicode'
True
Ричард Урбан
источник
2
В этом случае вы бы предпочли type(thing).__name__ == 'str'более type(thing) == strили isinstance(thing, str)? Также unicodeне существует в современных версиях Python.
vaultah