Как проверить (во время выполнения), если один класс является подклассом другого?

Скажем, что у меня есть класс Suit и четыре подкласса костюма: 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.

Ответ 1

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

Ответ 2

issubclass(class, classinfo)

Выдержка:

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

Ответ 3

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

Ответ 4

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

Ответ 5

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

Ответ 6

Использование 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)

Ответ 7

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 вверх по течению.

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

Ответ 8

//Наследование

    class A {
      int i = 10;
      public String getVal() {
        return "I'm 'A'";
      }
    }

    class B extends A {
      int j = 20;
      public String getVal() {
        return "I'm 'B'";
      }
    }

    class C extends B {
        int k = 30;
        public String getVal() {
          return "I'm 'C'";
        }
    }

//Методы

    public static boolean isInheritedClass(Object parent, Object child) {
      if (parent == null || child == null) {
        return false;
      } else {
        return isInheritedClass(parent.getClass(), child.getClass());
      }
    }

    public static boolean isInheritedClass(Class<?> parent, Class<?> child) {
      if (parent == null || child == null) {
        return false;
      } else {
        if (parent.isAssignableFrom(child)) {
          // is child or same class
          return parent.isAssignableFrom(child.getSuperclass());
        } else {
          return false;
        }
      }
    }

//Тестируем код

    System.out.println("isInheritedClass(new A(), new B()):" + isInheritedClass(new A(), new B()));
    System.out.println("isInheritedClass(new A(), new C()):" + isInheritedClass(new A(), new C()));
    System.out.println("isInheritedClass(new A(), new A()):" + isInheritedClass(new A(), new A()));
    System.out.println("isInheritedClass(new B(), new A()):" + isInheritedClass(new B(), new A()));


    System.out.println("isInheritedClass(A.class, B.class):" + isInheritedClass(A.class, B.class));
    System.out.println("isInheritedClass(A.class, C.class):" + isInheritedClass(A.class, C.class));
    System.out.println("isInheritedClass(A.class, A.class):" + isInheritedClass(A.class, A.class));
    System.out.println("isInheritedClass(B.class, A.class):" + isInheritedClass(B.class, A.class));

//Результат

    isInheritedClass(new A(), new B()):true
    isInheritedClass(new A(), new C()):true
    isInheritedClass(new A(), new A()):false
    isInheritedClass(new B(), new A()):false
    isInheritedClass(A.class, B.class):true
    isInheritedClass(A.class, C.class):true
    isInheritedClass(A.class, A.class):false
    isInheritedClass(B.class, A.class):false

Ответ 9

Согласно документации по Python, мы также можем использовать атрибут 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

Ответ 10

#issubclass(child,parent)

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

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