Учитывая класс Foo
(независимо от того, является ли он классом нового стиля или нет), как вы сгенерируете все базовые классы в любом месте иерархии наследования issubclass
?
Учитывая класс Foo
(независимо от того, является ли он классом нового стиля или нет), как вы сгенерируете все базовые классы в любом месте иерархии наследования issubclass
?
Ответы:
inspect.getmro(cls)
работает как для новых, так и для старых классов и возвращает то же самое, что и NewClass.mro()
: список класса и всех его классов-предков в порядке, используемом для разрешения метода.
>>> class A(object):
>>> pass
>>>
>>> class B(A):
>>> pass
>>>
>>> import inspect
>>> inspect.getmro(B)
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
inspect.getmro(obj)
вместо inspect.getmro(type(obj))
.
См. __bases__
Свойство, доступное на питоне class
, которое содержит кортеж базовых классов:
>>> def classlookup(cls):
... c = list(cls.__bases__)
... for base in c:
... c.extend(classlookup(base))
... return c
...
>>> class A: pass
...
>>> class B(A): pass
...
>>> class C(object, B): pass
...
>>> classlookup(C)
[<type 'object'>, <class __main__.B at 0x00AB7300>, <class __main__.A at 0x00A6D630>]
getmro
явно сказано: «Ни один класс не появляется в этом кортеже более одного раза»?
__bases__
поднимается только на один уровень . (Как и предполагает ваша рекурсивная утилита, но беглый взгляд на пример может не уловить этого.)
inspect.getclasstree()
создаст вложенный список классов и их баз. Использование:
inspect.getclasstree(inspect.getmro(IOError)) # Insert your Class instead of IOError.
python -c 'import inspect; from pprint import pprint as pp; pp(inspect.getclasstree(inspect.getmro(IOError)))'
вы можете использовать __bases__
кортеж объекта класса:
class A(object, B, C):
def __init__(self):
pass
print A.__bases__
Кортеж, возвращаемый функцией, __bases__
имеет все свои базовые классы.
Надеюсь, поможет!
__bases__
В python 3.7 вам не нужно импортировать inspect, результат выдаст type.mro.
>>> class A:
... pass
...
>>> class B(A):
... pass
...
>>> type.mro(B)
[<class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
>>>
Обратите внимание, что в python 3.x каждый класс наследуется от класса базового объекта.
Согласно документу Python , мы также можем просто использовать class.__mro__
атрибут или class.mro()
метод:
>>> class A:
... pass
...
>>> class B(A):
... pass
...
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
>>> A.__mro__
(<class '__main__.A'>, <class 'object'>)
>>> object.__mro__
(<class 'object'>,)
>>>
>>> B.mro()
[<class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
>>> A.mro()
[<class '__main__.A'>, <class 'object'>]
>>> object.mro()
[<class 'object'>]
>>> A in B.mro()
True
Хотя ответ Йохена очень полезен и верен, поскольку вы можете получить иерархию классов с помощью метода .getmro () модуля inspect, также важно подчеркнуть, что иерархия наследования Python выглядит следующим образом:
например:
class MyClass(YourClass):
Наследующий класс
например:
class YourClass(Object):
Унаследованный класс
Один класс может наследовать от другого - атрибуты класса наследуются - в частности, его методы наследуются - это означает, что экземпляры наследующего (дочернего) класса могут получить доступ к атрибутам унаследованного (родительского) класса.
экземпляр -> класс -> затем унаследованные классы
с помощью
import inspect
inspect.getmro(MyClass)
покажет вам иерархию в Python.