Как сравнить тип объекта в Python? - PullRequest
144 голосов
/ 02 апреля 2009

В основном я хочу сделать это:

obj = 'str'
type ( obj ) == string

Я пытался:

type ( obj ) == type ( string )

и это не сработало.

А как насчет других типов? Например, я не мог воспроизвести NoneType.

Ответы [ 14 ]

212 голосов
/ 02 апреля 2009
isinstance()

В вашем случае isinstance("this is a string", str) вернет True.

Вы также можете прочитать это: http://www.canonical.org/~kragen/isinstance/

35 голосов
/ 02 апреля 2009

isinstance работ:

if isinstance(obj, MyClass): do_foo(obj)

но , имейте в виду: если это похоже на утку и если это звучит как утка, то это утка

РЕДАКТИРОВАТЬ: Для типа None, вы можете просто сделать:

if obj is None: obj = MyClass()
31 голосов
/ 02 апреля 2009

Во-первых, избегайте всех сравнений типов. Они очень, очень редко нужны. Иногда они помогают проверить типы параметров в функции - даже это редко. Неправильный тип данных вызовет исключение, и это все, что вам когда-либо понадобится.

Все основные функции преобразования будут отображаться как равные функции типа.

type(9) is int
type(2.5) is float
type('x') is str
type(u'x') is unicode
type(2+3j) is complex

Есть еще несколько случаев.

isinstance( 'x', basestring )
isinstance( u'u', basestring )
isinstance( 9, int )
isinstance( 2.5, float )
isinstance( (2+3j), complex )

Никто, кстати, никогда не нуждается в такой проверке типов. Ни один не является единственным экземпляром NoneType. Ни один объект не является синглтоном. Просто проверьте None

variable is None

Кстати, не используйте вышеизложенное в целом. Используйте обычные исключения и собственный природный полиморфизм Python.

23 голосов
/ 02 апреля 2009

Для других типов проверьте модуль types :

>>> import types
>>> x = "mystring"
>>> isinstance(x, types.StringType)
True
>>> x = 5
>>> isinstance(x, types.IntType)
True
>>> x = None
>>> isinstance(x, types.NoneType)
True

P.S. Проверка типов - плохая идея.

13 голосов
/ 02 апреля 2009

Вы всегда можете использовать трюк type(x) == type(y), где y - это что-то с известным типом.

# check if x is a regular string
type(x) == type('')
# check if x is an integer
type(x) == type(1)
# check if x is a NoneType
type(x) == type(None)

Часто есть лучшие способы сделать это, особенно с любым недавним питоном. Но если вы хотите запомнить только одну вещь, вы можете запомнить это.

В этом случае лучшие способы будут:

# check if x is a regular string
type(x) == str
# check if x is either a regular string or a unicode string
type(x) in [str, unicode]
# alternatively:
isinstance(x, basestring)
# check if x is an integer
type(x) == int
# check if x is a NoneType
x is None

Обратите внимание на последний случай: в python есть только один экземпляр NoneType, это None. Вы будете часто видеть NoneType в исключениях (TypeError: 'NoneType' object is unsubscriptable - случается со мной все время ...), но вам вряд ли когда-нибудь понадобится ссылаться на него в коде.

Наконец, как указывает fengshaun, проверка типов в python - не всегда хорошая идея. Более питонно просто использовать значение, как если бы оно было ожидаемым вами типом, и перехватывать (или разрешать распространять) исключительные ситуации, возникающие из него.

6 голосов
/ 02 апреля 2009

Ты очень близко! string это модуль, а не тип. Вы, вероятно, хотите сравнить тип obj с объектом типа для строк, а именно str:

type(obj) == str  # this works because str is already a type

В качестве альтернативы:

type(obj) == type('')

Обратите внимание, что в Python 2, если obj является типом Unicode, ни один из вышеперечисленных не будет работать И не будет isinstance(). См. Комментарии Джона к этому сообщению, чтобы узнать, как обойти это ... Я пытался вспомнить это около 10 минут, но у меня был блок памяти!

5 голосов
/ 03 апреля 2009

Это потому, что вы должны написать

s="hello"
type(s) == type("")

тип принимает экземпляр и возвращает его тип. В этом случае вы должны сравнить два типа экземпляров.

Если вам необходимо выполнить упреждающую проверку, лучше проверить поддерживаемый интерфейс, чем тип.

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

Например, предположим, у вас есть этот код

def firstElement(parameter):
    return parameter[0]

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

import types

def firstElement(parameter):
    if type(parameter) != types.TupleType:
         raise TypeError("function accepts only a tuple")
    return parameter[0]

Это уменьшает возможность повторного использования этой процедуры. Это не сработает, если вы передадите список, или строку, или numpy.array. Что-то лучше было бы

def firstElement(parameter):
    if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))):
        raise TypeError("interface violation")
    return parameter[0]

но в этом нет никакого смысла: параметр [0] вызовет исключение, если протокол все равно не будет удовлетворен ... это, конечно, если вы не хотите предотвратить побочные эффекты или нет необходимости восстанавливаться после вызовов, которые вы могли вызвать раньше терпит неудачу. (Глупый) пример, просто чтобы подчеркнуть:

def firstElement(parameter):
    if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))):
        raise TypeError("interface violation")
    os.system("rm file")
    return parameter[0]

в этом случае ваш код вызовет исключение перед выполнением системного вызова (). Без проверки интерфейса вы удалили бы файл и вызвали исключение.

3 голосов
/ 09 февраля 2013

Использовать str вместо строки

type ( obj ) == str

Объяснение

>>> a = "Hello"
>>> type(a)==str
True
>>> type(a)
<type 'str'>
>>>
3 голосов
/ 02 апреля 2009

Я использую type(x) == type(y)

Например, если я хочу что-то проверить, это массив:

type( x ) == type( [] )

проверка строки:

type( x ) == type( '' ) or type( x ) == type( u'' )

Если вы хотите проверить None, используйте

x is None
2 голосов
/ 02 апреля 2009

я думаю, что это должно сделать

if isinstance(obj, str)
...