Как проверить (во время выполнения), является ли один класс подклассом другого? - PullRequest
163 голосов
/ 06 февраля 2011

Допустим, у меня есть классный костюм и четыре подкласса костюма: Heart, Spade, Diamond, Club.

class Suit:
   ...
class Heart(Suit):
   ...
class Spade(Suit):
   ...
class Diamond(Suit):
   ...
class Club(Suit):
   ...

У меня есть метод, который получает костюм в качестве параметра, который является объектом класса, а не экземпляром. Точнее, он может получить только одно из четырех значений: Heart, Spade, Diamond, Club. Как я могу сделать утверждение, которое гарантирует такую ​​вещь? Что-то вроде:

def my_method(suit):
   assert(suit subclass of Suit)
   ...

Я использую Python 3.

Ответы [ 9 ]

188 голосов
/ 06 февраля 2011

Вы можете использовать issubclass() вот так assert issubclass(suit, Suit).

39 голосов
/ 06 февраля 2011

issubclass(class, classinfo)

Выдержка:

Возвращает true, если class является подклассом (прямым, косвенным или виртуальным) classinfo.

25 голосов
/ 06 февраля 2011

Вы можете использовать isinstance, если у вас есть экземпляр, или issubclass, если у вас есть класс.Обычно считается плохой идеей.Обычно в Python вы выясняете, способен ли объект на что-то, пытаясь сделать это с ним.

20 голосов
/ 18 августа 2014

Булева функция issubclass(sub, sup) возвращает true, если данный подкласс sub действительно является подклассом суперкласса sup.

1 голос

issubclass минимальный работоспособный пример

Вот более полный пример с некоторыми утверждениями:

#!/usr/bin/env python3

class Base:
    pass

class Derived(Base):
    pass

base = Base()
derived = Derived()

# Basic usage.
assert issubclass(Derived, Base)
assert not issubclass(Base, Derived)

# True for same object.
assert issubclass(Base, Base)

# Cannot use object of class.
try:
    issubclass(derived, Base)
except TypeError:
    pass
else:
    assert False

# Do this instead.
assert isinstance(derived, Base)

GitHub upstream .

Протестировано в Python 3.5.2.

1 голос
/ 09 марта 2015

Использование issubclass казалось чистым способом записи уровней журналов. Это немного странно при использовании ... но кажется чище, чем другие варианты.

class Error(object): pass
class Warn(Error): pass
class Info(Warn): pass
class Debug(Info): pass

class Logger():
    LEVEL = Info

    @staticmethod
    def log(text,level):
        if issubclass(Logger.LEVEL,level):
            print(text)
    @staticmethod
    def debug(text):
        Logger.log(text,Debug)   
    @staticmethod
    def info(text):
        Logger.log(text,Info)
    @staticmethod
    def warn(text):
        Logger.log(text,Warn)
    @staticmethod
    def error(text):
        Logger.log(text,Error)
1 голос
/ 06 февраля 2011

Вы можете использовать встроенный класс Issub. Но проверка типов обычно считается излишней, потому что вы можете использовать утку.

0 голосов
/ 10 июля 2019

В соответствии с Python doc , мы также можем использовать атрибут class.__mro__ или class.mro() метод:

class Suit:
    pass
class Heart(Suit):
    pass
class Spade(Suit):
    pass
class Diamond(Suit):
    pass
class Club(Suit):
    pass

>>> Heart.mro()
[<class '__main__.Heart'>, <class '__main__.Suit'>, <class 'object'>]
>>> Heart.__mro__
(<class '__main__.Heart'>, <class '__main__.Suit'>, <class 'object'>)

Suit in Heart.mro()  # True
object in Heart.__mro__  # True
Spade in Heart.mro()  # False
0 голосов
/ 13 сентября 2016
#issubclass(child,parent)

class a:
    pass
class b(a):
    pass
class c(b):
    pass

print(issubclass(c,b))#it returns true
...