Heim > Artikel > Backend-Entwicklung > In Python sind __subclasscheck__ und __subclasshook__ zwei spezielle Methoden
Python ist eine universell anpassbare und effektive Programmiersprache, die seit langem immer beliebter wird. Die objektorientierten Funktionen von Python ermöglichen die Implementierung hochwertiger Funktionen wie Vererbung und Polymorphismus. In diesem Artikel werfen wir einen tiefen Einblick in zwei wenig bekannte, aber faszinierende Techniken, die eine benutzerdefinierte Vererbungsprüfung in Python ermöglichen: Subclasscheck und Subclasshook.
In Python ist es nicht ungewöhnlich, mithilfe der integrierten Funktion issubclass() festzustellen, ob eine Klasse eine Unterklasse einer anderen Klasse ist. Standardmäßig untersucht diese Funktion den Vererbungsbaum, um Verbindungen zwischen Klassen zu ermitteln. Allerdings bietet Python auch eine Möglichkeit, dieses Standardverhalten mithilfe der einzigartigen Methoden subclasscheck und subclasshook zu überschreiben.
__subclasscheck__(cls) − Testen Sie, ob eine Klasse eine Unterklasse aller anderen Klassen ist, indem Sie diese Technik mit der Funktion issubclass() aufrufen. Standardmäßig werden die Ergebnisse des üblichen geerbten Tests zurückgegeben, es kann jedoch überschrieben werden, um dieses Verhalten zu ändern.
__subclasshook__(cls) − Diese Methode kann in einer abstrakten Basisklasse (ABC) definiert werden, um die von issubclass() durchgeführte Unterklassenprüfung anzupassen. Es wird von der Standardimplementierung von subclasscheck in ABC aufgerufen.
Um klar zu verstehen, wie die Subclasshook-Methode funktioniert, sehen wir uns ein Beispiel an. Angenommen, wir haben eine abstrakte Basisklasse namens „Shape“, die über zwei erforderliche Methoden verfügt: „area“ und „perimeter“. Jede Klasse, die als Unterklasse von „Shape“ betrachtet werden möchte, muss diese Methoden implementieren.
Schritt 1 − Bestimmen Sie die abstrakte Basisklasse „Shape“ mit zwei spezifischen Methoden: „Area“ und „Perimeter“.
Schritt 2 − Generieren Sie eine benutzerdefinierte Klasse „Circle“, die die angegebenen Methoden „area“ und „perimeter“ implementiert.
Schritt 3 − Überschreiben Sie die Subclasshook-Methode in der Klasse „Shape“, um benutzerdefinierte Kriterien für die Bestimmung anzugeben, ob eine Klasse eine Unterklasse ist. In diesem Fall besteht das Kriterium darin, dass die Klasse über die Methoden „Fläche“ und „Umfang“ verfügen sollte.
Schritt 4 − Verwenden Sie die Funktion issubclass(), um zu testen, ob „Circle“ eine Unterklasse von „Shape“ ist. Bei Verwendung einer benutzerdefinierten Unterklassen-Hook-Methode ist das Ergebnis „True“, da „Circle“ die benutzerdefinierte Bedingung erfüllt.
Jetzt erstellen wir eine benutzerdefinierte Klasse „Circle“, die diese Methoden implementiert -
from abc import ABCMeta, abstractmethod class Shape(metaclass=ABCMeta): @abstractmethod def area(self): pass @abstractmethod def perimeter(self): pass class Circle: def __init__(self, radius): self.radius = radius def area(self): return 3.14 * self.radius * self.radius def perimeter(self): return 2 * 3.14 * self.radius print(issubclass(Circle, Shape))
Obwohl die Klasse „Circle“ die erforderliche Methode implementiert, gibt die Funktion issubclass() dennoch „False“ zurück, wenn sie prüft, ob „Circle“ eine Unterklasse von „Shape“ ist -
False
Hier kommt die Subclasshook-Methode ins Spiel. Wir können diese Methode in der Klasse „Shape“ überschreiben, um benutzerdefinierte Kriterien zur Bestimmung anzugeben, ob eine Klasse eine Unterklasse ist –
class Shape(metaclass=ABCMeta): @abstractmethod def area(self): pass @abstractmethod def perimeter(self): pass @classmethod def __subclasshook__(cls, other): if cls is Shape: if all(hasattr(other, method) for method in ['area', 'perimeter']): return True return NotImplemented print(issubclass(Circle, Shape))
Ausgabe
Wenn wir prüfen, ob „Circle“ eine Unterklasse von „Shape“ ist, ist die Ausgabe wie folgt.
True
In einigen Fällen möchten Sie möglicherweise die Subclasscheck-Methode selbst überschreiben, anstatt einen Subclasshook zu verwenden. Dies kann eine zusätzliche erstklassige granulare Kontrolle für Vererbungstests bieten. Hier ist ein Beispiel −
Schritt 1 − Bestimmen Sie die benutzerdefinierte Basisklasse „CustomBase“, die die Unterklassenprüfmethode überschreibt. Anstatt normale Vererbungsverbindungen zu testen, testen wir, ob die Unterklasse über eine aufrufbare „magic_attribute“-Methode verfügt.
Schritt 2− Generieren Sie zwei Klassen, „DerivedWithMagic“ und „DerivedWithoutMagic“. Ersteres verfügt über eine „magic_attribute“-Methode, letzteres nicht.
第 3 步 − 利用 issubclass() 函数来测试“DerivedWithMagic”和“DerivedWithoutMagic”是否是“CustomBase”的子类。对于“DerivedWithMagic”,结论为“True”,因为它具有所需的“magic_attribute”方法;对于“DerivedWithoutMagic”,结论为“False”,因为它不再具有指定的方法。
class CustomBase: def __subclasscheck__(self, subclass): return (hasattr(sub class, "magic_attribute") and callable(getattr(subclass, "magic_attribute"))) class DerivedWithMagic: def magic_attribute(self): pass class DerivedWithoutMagic: pass print(issubclass(DerivedWithMagic, CustomBase)) print(issubclass(DerivedWithoutMagic, CustomBase))
输出
如果我们检查“Circle”是否是“Shape”的子类,则输出如下。
True False
虽然 Python 中的默认继承机制适用于大多数场景,但在某些情况下,使用 __subclasscheck__ 和 __subclasshook__ 自定义子类检查可能会有所帮助 -
**协议执行** − 通过使用这些方法,您可以强制执行子类必须遵守的某些协议。在前面的实例中,我们决定任何被视为“Shape”子类的类都必须执行“area”和“perimeter”方法。
**混合课程** − Mixin 类的创建是为了向其他类提供特定的行为,但它们并不意味着用作独立的类。您可以使用 __subclasscheck__ 或 __subclasshook__ 定义自定义继承策略,通过利用 mixin 作为子类来识别类,尽管它们不会立即继承它。
**松散耦合** − 在某些情况下,最大限度地减少软件系统中组件之间的依赖关系是有益的。通过使用 __subclasscheck__ 和 __subclasshook__,您可以在类之间建立关系,而无需创建严格的继承层次结构。
Python 中的 __subclasscheck__ 和 __subclasshook__ 方法提供了一种强大的方法来自定义继承检查。当您想要强制执行子类关系的特定要求或提供更灵活的继承结构时,这些方法特别有用。通过理解和利用这些特殊方法,您可以创建适应性更强、更健壮的 Python 程序。
Das obige ist der detaillierte Inhalt vonIn Python sind __subclasscheck__ und __subclasshook__ zwei spezielle Methoden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!