2010-07-14 4 views
1

У меня есть список переменных .. внутри списка есть строки, числа и объекты класса. Мне нужно выполнить логику на основе каждого типа данных. У меня возникают проблемы с обнаружением объектов класса и ветвлением моей логики в этот момент.Как определить тип данных внутри переменной python?

if(type(lists[listname][0]).__name__ == 'str'): # <--- this works for strings 
elif(type(lists[listname][0]).__name__ == 'object'): <--- this does not work for classes 

во второй строке кода выше, имя переменная содержит «адрес» в качестве имени класса. Я надеялся, что он будет содержать «класс» или «объект», чтобы я мог разветвить мою программу. В будущем у меня будет много разных типов объектов, поэтому немного логично не применять логику для каждого имени класса, «Адрес» «Лицо» и т. Д.

, пожалуйста, дайте мне знать, если мой вопрос нуждается в уточнении.

спасибо !!

ответ

2

Я думаю, вы хотите функцию isinstance.

if isinstance(o, ClassName): 

Однако, вы должны сначала убедиться, что o является объектом, вы можете использовать type для этого.

+0

спасибо, я получил немного больше в своем приложении, используя это. – djmc

4

FYI: это также делает разницу, если его класс нового стиля или нет:

# python 
type(1).__name__ 
'int' 
type('1').__name__ 
'str' 
class foo(object): 
    pass 
type(foo()).__name__ 
'foo' 
class bar: 
    pass 
type(bar()).__name__ 
'instance' 

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

Однако, вы можете взять его на один шаг дальше:

type(bar().__class__).__name__ 
'classobj' 
type(foo().__class__).__name__ 
'type' 

И всегда искать 'classobj' или 'типа'. (. Или имя метакласса, если он есть)

+0

ОК спасибо, я думаю, что понимаю все эти примеры. Я скорее не ищу метакласса, потому что я не всегда знаю, что это будет. Я надеялся найти способ обнаружить базовый объект постоянно – djmc

+0

без проблем, lemme знаю, если вам нужно что-нибудь еще. – eruciform

-1

Если вы заинтересованы только в обработке двух типов специально, вы можете проверить их явно с помощью isinstance, а затем обрабатывать остатки:

import numbers 

for item in list: 
    if isinstance(item, basestring): # (str, unicode) 
     do_string_thing(item) 
    elif isinstance(item, numbers.Real): # (int, float, long) 
     do_number_thing(item) 
    else: 
     do_object_thing(item) 
+0

Может кто-нибудь объяснить, почему это было проголосовано? Я чувствую, что для меня и других читателей было бы полезно понять, что было не так с моим предложением. – AdmiralNemo

+0

Некоторые люди считают isinstance() инструментом последней инстанции. См. Http://www.canonical.org/~kragen/isinstance/ для обоснования. –

+0

Согласно PEP 8, «сравнение типов объектов всегда должно использовать isinstance() вместо сравнения типов напрямую." – AdmiralNemo

2

В Python обычно используется обработка исключений, чтобы решить, какой путь кода следует принять; проверяя точный тип объекта (с isinstance()), чтобы решить, что с ним делать, не рекомендуется.

Например, скажите, что вы хотите сделать, если это строка, напечатайте ее в «случае заголовка», и если это объект, вы хотите вызвать на нем определенный метод. Итак:

try: 
    # is it an object with a particular method? 
    lists[listname][0].particularMethod() 
except AttributeError: 
    # no, it doesn't have particularMethod(), 
    # so we expect it to be a string; print it in title case 
    print lists[listname][0].title() 
+0

+1 Хороший совет! Проверка типов следует избегать в python даже больше, чем на некоторых других языках, чтобы можно было использовать любой совместимый объект. Python не определяет интерфейсы, потому что любой объект должен использоваться в любом месте, если он реализует необходимые методы. – zvone

+0

ok Я предполагаю, что могу это сделать здесь. Это не проблема для этого приложения, но для будущей ссылки есть проблема с эффективностью использования Обработка исключений таким образом? – djmc

+0

Не важно. Если вы делали это kajillions раз, вы могли бы создать класс, который наследует от str и реализует specificMethod(), и использовать экземпляры этого класса в вашем списке вместо str, а затем вы просто вызываете specialMethod() на все. –

Смежные вопросы