Почему тип (classInstance) возвращает «экземпляр»? - PullRequest
11 голосов
/ 24 июня 2010

У меня есть метод, который принимает параметр, который может быть нескольких типов, и должен делать то или иное в зависимости от типа, но если я проверяю тип указанного параметра, я не получаю «реальный»типа, я всегда получаю <type 'instance'>, и это портит мои сравнения.

У меня есть что-то вроде:

from classes import Class1
from classes import Class2
# Both classes are declared in the same file.
# I don't know if that can be a problem         #
# ... #
def foo(parameter)
    if (type(parameter) == type(Class1()):
    # ... #
    elif (type(parameter) == type(Class2()):
    # ... #

И так как type(parameter) возвращает <type 'instance'> и type(Class1()) равно <type 'instance'>, получается, что даже если параметр являетсяэкземпляр Class2, он идет в первое сравнение ...

Кстати, str(parameter.__class__) правильно показывает classes.Class1.Я думаю, я всегда мог бы использовать это, но я хотел бы понять, что происходит ... Я провел десятки таких сравнений, и все они работали правильно ...

Спасибо!:)

Ответы [ 3 ]

16 голосов
/ 24 июня 2010

Классы старого стиля делают это.Получите ваши классы от object в их определениях.

10 голосов
/ 24 июня 2010

вы действительно должны использовать isinstance:

In [26]: def foo(param):
   ....:     print type(param)
   ....:     print isinstance(param, Class1)
   ....:

In [27]: foo(x)
<type 'instance'>
True

Тип лучше для встроенных типов.

9 голосов
/ 24 июня 2010

Тот факт, что type(x) возвращает один и тот же тип объекта для всех экземпляров x устаревших классов, известных как в старом стиле, является одним из многих вызывающих недовольство недостатков этих классов - к сожалению, они должны остаться (ипо умолчанию для класса без базы) в Python 2.* по причинам обратной совместимости.

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

__metaclass__ = type

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

...