Как сравнить тип объекта в Python?
В основном я хочу сделать это:
obj = 'str'
type ( obj ) == string
Я старался:
type ( obj ) == type ( string )
и это не сработало.
Кроме того, как насчет других типов? Например, я не мог воспроизвести NoneType
,
15 ответов
isinstance()
В твоем случае, isinstance("this is a string", str)
вернусь True
,
Вы также можете прочитать это: http://www.canonical.org/~kragen/isinstance/
Во-первых, избегайте всех сравнений типов. Они очень, очень редко нужны. Иногда они помогают проверить типы параметров в функции - даже это редко. Неправильный тип данных вызовет исключение, и это все, что вам когда-либо понадобится.
Все основные функции преобразования будут отображаться как равные функции типа.
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. Ни один объект не является синглтоном. Просто проверьте Нет
variable is None
Кстати, не используйте вышеизложенное в целом. Используйте обычные исключения и собственный природный полиморфизм Python.
isinstance
работает:
if isinstance(obj, MyClass): do_foo(obj)
но имейте в виду: если это похоже на утку, и если это звучит как утка, это утка.
РЕДАКТИРОВАТЬ: Для типа None, вы можете просто сделать:
if obj is None: obj = MyClass()
Для других типов, проверьте модуль типов:
>>> import types
>>> x = "mystring"
>>> isinstance(x, types.StringType)
True
>>> x = 5
>>> isinstance(x, types.IntType)
True
>>> x = None
>>> isinstance(x, types.NoneType)
True
PS Проверка типов - плохая идея.
Вы всегда можете использовать 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
Обратите внимание на последний случай: существует только один экземпляр NoneType
в питоне, и это None
, Вы увидите NoneType много в исключениях (TypeError: 'NoneType' object is unsubscriptable
- случается со мной все время..) но вам вряд ли когда-нибудь понадобится ссылаться на это в коде.
Наконец, как указывает fengshaun, проверка типов в python - не всегда хорошая идея. Более питонно просто использовать значение, как если бы оно было ожидаемым вами типом, и перехватывать (или разрешать распространять) исключения, возникающие из него.
Использование isinstance(object, type)
, Как указано выше, это легко использовать, если вы знаете правильный type
например,
isinstance('dog', str) ## gives bool True
Но для более эзотерических объектов это может быть трудно использовать. Например:
import numpy as np
a = np.array([1,2,3])
isinstance(a,np.array) ## breaks
но вы можете сделать этот трюк:
y = type(np.array([1]))
isinstance(a,y) ## gives bool True
Поэтому я рекомендую создать экземпляр переменной (y
в данном случае) с типом объекта, который вы хотите проверить (например, type(np.array())
), затем с помощью isinstance
,
Ты очень близко! string
это модуль, а не тип. Вы, вероятно, хотите сравнить тип obj
против типа объекта для строк, а именно str
:
type(obj) == str # this works because str is already a type
В качестве альтернативы:
type(obj) == type('')
Обратите внимание, в Python 2, если obj
является типом Unicode, тогда ни один из вышеупомянутых не будет работать. Не будет isinstance()
, См. Комментарии Джона к этому посту, чтобы узнать, как обойти это... Я пытался вспомнить это около 10 минут, но у меня был блок памяти!
Используйте строку вместо строки
type ( obj ) == str
объяснение
>>> a = "Hello"
>>> type(a)==str
True
>>> type(a)
<type 'str'>
>>>
Это потому, что вы должны написать
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]
в этом случае ваш код вызовет исключение перед выполнением вызова system(). Без проверки интерфейса вы бы удалили файл, а затем вызвали исключение.
Я использую type(x) == type(y)
Например, если я хочу проверить что-то, это массив:
type( x ) == type( [] )
проверка строки:
type( x ) == type( '' ) or type( x ) == type( u'' )
Если вы хотите проверить None, используйте
x is None
Чтобы получить тип, используйте __class__
член, как в unknown_thing.__class__
Разговор о наборе утки здесь бесполезен, потому что он не отвечает на совершенно хороший вопрос. В моем коде приложения мне никогда не нужно знать тип чего-либо, но все равно полезно иметь способ узнать тип объекта. Иногда мне нужно получить реальный класс для проверки модульного теста. Утиная печать мешает, потому что все возможные объекты имеют одинаковый API, но только один является правильным. Кроме того, иногда я поддерживаю чужой код и не знаю, какой тип объекта мне передали. Это моя самая большая проблема с динамически типизированными языками, такими как Python. Версия 1 очень проста и быстро разрабатывается. Версия 2 - это проблема, особенно если вы не написали версию 1. Поэтому иногда, когда я работаю с функцией, которую я не писал, мне нужно знать тип параметра, просто чтобы я знал какие методы я могу вызвать на это.
Вот где __class__
Параметр пригодится. Это (насколько я могу судить) - лучший способ (возможно, единственный способ) получить тип объекта.
Тип не работает на определенных классах. Если вы не уверены в типе объекта, используйте __class__
метод, как так:
>>>obj = 'a string'
>>>obj.__class__ == str
True
Также смотрите эту статью - http://www.siafoo.net/article/56
Вы можете сравнить классы для проверки уровня.
#!/usr/bin/env python
#coding:utf8
class A(object):
def t(self):
print 'A'
def r(self):
print 'rA',
self.t()
class B(A):
def t(self):
print 'B'
class C(A):
def t(self):
print 'C'
class D(B, C):
def t(self):
print 'D',
super(D, self).t()
class E(C, B):
pass
d = D()
d.t()
d.r()
e = E()
e.t()
e.r()
print isinstance(e, D) # False
print isinstance(e, E) # True
print isinstance(e, C) # True
print isinstance(e, B) # True
print isinstance(e, (A,)) # True
print e.__class__ >= A, #False
print e.__class__ <= C, #False
print e.__class__ < E, #False
print e.__class__ <= E #True
Поскольку type возвращает объект, вы можете получить доступ к имени объекта, используя object. имя
Пример:
years = 5
user = {'name':'Smith', 'age':20}
print(type(a).__name__)
вывод: 'целое'
print(type(b).__name__ )
вывод: 'дикт'