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')); // truebool(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); // truetrue true
Java: Оператор instanceof проверяет, является ли объект экземпляром класса или его подкласса. Метод Class.isAssignableFrom() проверяет, можно ли присвоить ссылку на объект данного класса.
class Parent {}
class Child extends Parent {}
System.out.println(Parent.class.isAssignableFrom(Child.class)); // truetrue
C#: Метод Type.IsSubclassOf() выполняет аналогичную проверку. Также существует метод IsAssignableFrom.
class Parent {}
class Child : Parent {}
Console.WriteLine(typeof(Child).IsSubclassOf(typeof(Parent))); // trueTrue
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)) # TrueTrue 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)) # TrueTrue
Динамическая проверка в метаклассах или фабриках классов.
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)) # TrueTrue