Issubclass: примеры (PYTHON)

Функция issubclass в Python: примеры и подробное описание
Раздел: Встроенные функции, Интроспекция
issubclass(class, classinfo): bool

Функция issubclass в Python

Функция issubclass() является встроенной функцией Python, которая проверяет, является ли один класс подклассом другого. Ее основное применение - определение отношений наследования в объектно-ориентированном программировании.

Функция используется для проверки иерархии классов во время выполнения программы. Она полезна при динамическом создании или анализе типов, в метапрограммировании, а также для валидации входных данных в плагинах и фреймворках.

Синтаксис функции: issubclass(class, classinfo).

Аргументы:

  • class - проверяемый класс.
  • classinfo - класс, кортеж классов или иерархия типов, по отношению к которой проверяется аргумент class.

Возвращаемое значение:

  • True, если класс class является подклассом (прямым, косвенным или виртуальным) любого класса в classinfo.
  • False, если класс не является подклассом.
  • Если аргумент class не является классом, возникает исключение TypeError.
  • Если аргумент classinfo не является классом или кортежем классов, также возникает исключение TypeError.

Примеры использования issubclass

Простейший случай проверки прямого наследования.

class Parent:
    pass

class Child(Parent):
    pass

print(issubclass(Child, Parent))
True

Проверка с использованием кортежа классов. Функция вернет True, если class является подклассом хотя бы одного из классов в кортеже.

class A:
    pass

class B:
    pass

class C(A):
    pass

print(issubclass(C, (A, B)))
True

Если класс не является подклассом, возвращается False.

class X:
    pass

class Y:
    pass

print(issubclass(X, Y))
False

Класс считается подклассом самого себя.

class MyClass:
    pass

print(issubclass(MyClass, MyClass))
True

Похожие функции в Python

В Python существуют другие функции для проверки типов и отношений между объектами.

  • isinstance(object, classinfo): Проверяет, является ли объект экземпляром класса или подкласса. Эта функция работает с экземплярами объектов, в то время как issubclass работает только с классами. isinstance обычно предпочтительнее для проверки типов объектов, так как она учитывает наследование и поддерживает кортежи типов.
  • type(object): Возвращает точный тип объекта. Она не учитывает наследование. Используется, когда требуется точное совпадение типа, а не проверка по иерархии.

Выбор между issubclass и isinstance зависит от контекста: issubclass применяется для проверки отношений между классами (например, при регистрации классов в системе плагинов), а isinstance - для проверки экземпляров объектов (например, при валидации аргументов функции).

Аналоги функции в других языках

PHP: Функция is_subclass_of() проверяет, содержит ли объект или класс указанный класс в числе своих родителей.

class Parent {}
class Child extends Parent {}

var_dump(is_subclass_of('Child', 'Parent')); // true
var_dump(is_subclass_of(new Child(), 'Parent')); // true
bool(true)
bool(true)

JavaScript: В JavaScript нет прямой функции, но можно использовать оператор instanceof для проверки экземпляров или сравнение цепочек прототипов. Для классов ES6 есть свойство .prototype.

class Parent {}
class Child extends Parent {}

console.log(Child.prototype instanceof Parent); // true
console.log(new Child() instanceof Parent); // true
true
true

Java: Оператор instanceof проверяет, является ли объект экземпляром класса или его подкласса. Метод Class.isAssignableFrom() проверяет, можно ли присвоить ссылку на объект данного класса.

class Parent {}
class Child extends Parent {}

System.out.println(Parent.class.isAssignableFrom(Child.class)); // true
true

C#: Метод Type.IsSubclassOf() выполняет аналогичную проверку. Также существует метод IsAssignableFrom.

class Parent {}
class Child : Parent {}

Console.WriteLine(typeof(Child).IsSubclassOf(typeof(Parent))); // true
True

Golang: В Go нет классического наследования. Для проверки типов используется утверждение типа или рефлексия.

Kotlin: Функция-расширение KClass.isSubclassOf() проверяет отношение наследования.

Типичные ошибки при использовании

Передача экземпляра объекта вместо класса в первый аргумент вызывает исключение TypeError.

class MyClass:
    pass

obj = MyClass()
try:
    print(issubclass(obj, MyClass))
except TypeError as e:
    print(f\"Ошибка: {e}\")
Ошибка: issubclass() arg 1 must be a class

Передача некорректного типа данных в качестве второго аргумента (не класс и не кортеж классов) также вызывает TypeError.

class MyClass:
    pass

try:
    print(issubclass(MyClass, \"string\"))
except TypeError as e:
    print(f\"Ошибка: {e}\")
Ошибка: issubclass() arg 2 must be a class or tuple of classes

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

class MyClass:
    pass

print(issubclass(MyClass, ()))
False

Изменения в последних версиях Python

Начиная с Python 3.10, параметр classinfo может быть Union Type, представленный через оператор |. В более ранних версиях classinfo должен был быть классом или кортежем классов.

# Работает в Python 3.10+
from typing import Union

class A: pass
class B: pass
class C(A): pass

print(issubclass(C, A | B))  # True
True

Также в Python 3.10 улучшены сообщения об ошибках для некоторых некорректных случаев использования функции.

Расширенные примеры issubclass

Проверка с абстрактными базовыми классами (ABC) из модуля collections.abc.

from collections.abc import Iterable, Sized

class MyList(list):
    pass

print(issubclass(MyList, Iterable))  # True
print(issubclass(MyList, Sized))     # True
True
True

Использование с несколькими уровнями наследования.

class GrandParent:
    pass

class Parent(GrandParent):
    pass

class Child(Parent):
    pass

print(issubclass(Child, GrandParent))  # True (косвенное наследование)
True

Проверка виртуальных подклассов, зарегистрированных с помощью ABCMeta.register().

from collections.abc import Iterable

class NotIterable:
    pass

Iterable.register(NotIterable)  # Регистрация виртуального подкласса
print(issubclass(NotIterable, Iterable))  # True
True

Динамическая проверка в метаклассах или фабриках классов.

class PluginBase:
    pass

class Plugin1(PluginBase):
    pass

class NotPlugin:
    pass

plugin_candidates = [Plugin1, NotPlugin, dict]
valid_plugins = [cls for cls in plugin_candidates if issubclass(cls, PluginBase)]
print(valid_plugins)
[]

Проверка с использованием типов из модуля typing, таких как Generic.

from typing import Generic, TypeVar

T = TypeVar('T')

class MyGeneric(Generic[T]):
    pass

class Concrete(MyGeneric[int]):
    pass

print(issubclass(Concrete, MyGeneric))  # True
True

питон issubclass function comments

En
Issubclass Check if class is subclass