Как я могу определить иерархию классов для данного экземпляра объекта в Python? - PullRequest
2 голосов
/ 22 октября 2009

Есть ли способ обнаружить базовый класс в Python?

Для заданных следующих определений классов:

class A:
   def speak(self):
      print "Hi"

class B(A):
   def getName(self):
      return "Bob"

Если я получил экземпляр объекта, я легко могу определить, что это B, выполнив следующее:

instance = B()
print B.__class__.__name__

Что печатает имя класса 'B', как и ожидалось.

Есть ли в любом случае обнаружить, что экземпляр объекта наследует от базового класса, а также фактического класса?

Или это просто не так, как работают объекты в Python?

Ответы [ 4 ]

6 голосов
/ 22 октября 2009

Модуль проверки действительно мощный:

>>> import inspect

>>> inst = B()
>>> inspect.getmro(inst.__class__)
(<class __main__.B at 0x012B42A0>, <class __main__.A at 0x012B4210>)
5 голосов
/ 22 октября 2009
b = B()
b.__class__
b.__class__.__base__
b.__class__.__bases__
b.__class__.__base__.__subclasses__()

Я настоятельно рекомендую проверить ipython и использовать завершение вкладки: -)

4 голосов
/ 22 октября 2009

Другой способ получить иерархию классов - получить доступ к атрибуту mro :

class A(object):
    pass
class B(A):
    pass
instance = B()
print(instance.__class__.__mro__)
# (<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)

Обратите внимание, что в Python 2.x вы должны использовать объекты "нового стиля", чтобы убедиться, что они имеют mro атрибут. Вы делаете это, заявляя

class A(object):

вместо

class A():

См. http://www.python.org/doc/newstyle/ и http://www.python.org/download/releases/2.3/mro/ для получения дополнительной информации об объектах нового стиля и mro (порядок разрешения методов).

В Python 3.x все объекты являются объектами нового стиля, поэтому вы можете использовать mro и просто объявлять объекты следующим образом:

class A():
0 голосов
/ 22 октября 2009

Если вместо обнаружения базового класса (т.е. отражения) вы заранее знаете нужный класс, вы можете использовать следующие встроенные функции

например:

# With classes from original Question defined
>>> instance = A()
>>> B_instance = B()
>>> isinstance(instance, A)
True
>>> isinstance(instance, B)
False
>>> isinstance(B_instance, A) # Note it returns true if instance is a subclass
True
>>> isinstance(B_instance, B)
True
>>> issubclass(B, A)
True

isinstance (объект, classinfo) Вернуть true, если аргумент объекта является экземпляром classinfo аргумент или (прямой или косвенный) его подкласс. Также верните true, если classinfo - это объект типа и объект является объектом этого типа. Если объект не является экземпляром класса или объектом данного типа, функция всегда возвращает ложь Если classinfo не объект класса, ни объект типа, это может быть кортежем класса или типа объекты или могут рекурсивно содержать другие такие кортежи (другая последовательность типы не принимаются). Если classinfo не является классом, типом или кортежем классы, типы и такие кортежи, Возникла исключительная ситуация TypeError. Изменено в версии 2.2: поддержка кортежа информация о типе была добавлена.

issubclass (class, classinfo) Верните true, если class является подклассом (прямым или косвенным) classinfo. класс считается подклассом сам. classinfo может быть кортежем объекты класса, в этом случае каждый запись в classinfo будет проверена. В любой другой случай, исключение TypeError Поднялся. Изменено в версии 2.3: Поддержка кортежа типа информация была добавлена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...