搜索
首页后端开发Python教程在Python中,__subclasscheck__和__subclasshook__是两个特殊方法

在Python中,__subclasscheck__和__subclasshook__是两个特殊方法

Sep 14, 2023 pm 12:37 PM
python中的特殊方法__subclasscheck__方法__subclasshook__方法

在Python中,__subclasscheck__和__subclasshook__是两个特殊方法

Python 是一种普遍适应性强且有效的编程语言,长期以来一直受到广泛欢迎。 Python 面向对象的特性允许执行一些高质量的功能,例如继承和多态性。在这篇文章中,我们将深入研究两种鲜为人知但迷人的技术,它们允许在 Python 中进行定制设计的继承检查:subclasscheck 和 subclasshook。

什么是 Subclasscheck 和 Subclasshook?

在 Python 中,通过使用内置的 issubclass() 函数来确定一个类是否是其他类的子类并不罕见。默认情况下,该函数检查继承树来决定课程之间的连接。然而,Python 还提供了一种使用独特的方法 subclasscheck 和 subclasshook 来覆盖此默认行为的方法。

  • __subclasscheck__(cls)  通过使用 issubclass() 函数调用此技术来测试某个类别是否是所有其他类的子类。默认情况下,它返回通常继承测试的结果,但可以重写它以改变此行为。

  • __subclasshook__(cls)  可以在抽象基类 (ABC) 中定义此方法,以自定义 issubclass() 执行的子类检查。它由 ABC 中 subclasscheck 的默认实现调用。

子类钩子方法

为了清楚地了解 subclasshook 方法的工作原理,让我们看一个示例。假设我们有一个名为“Shape”的抽象基类,它有两个必需的方法:“area”和“perimeter”。任何希望被视为“Shape”子类的类都必须实现这些方法。

第 1 步  使用两种特定方法确定抽象基类“形状”:“面积”和“周长”。

第 2 步  生成一个自定义类“Circle”,该类实现指定的方法“area”和“perimeter”。

第 3 步 − 重写 'Shape' 类中的 subclasshook 方法以指定用于确定类是否为子类的自定义标准。在这种情况下,标准是该类应该具有“面积”和“周长”方法。

第 4 步 − 使用 issubclass() 函数测试“Circle”是否是“Shape”的子类。使用自定义子类挂钩方法,结果为“True”,因为“Circle”满足自定义条件。

示例

现在,让我们创建一个实现这些方法的自定义类“Circle” -

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))

即使“Circle”类实现了所需的方法,issubclass() 函数在检查“Circle”是否是“Shape”的子类时仍将返回“False” -

输出

False

这就是 subclasshook 方法发挥作用的地方。我们可以在“Shape”类中重写此方法,以指定确定一个类是否为子类的自定义标准 -

示例

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))

输出

如果我们检查“Circle”是否是“Shape”的子类,则输出如下。

True

子类检查方法

在某些情况下,您可能想要重写 subclasscheck 方法本身,而不是使用 subclasshook。这可以为继承测试提供额外的一流粒度控制。这是一个示例

第 1 步  确定覆盖子类检查方法的自定义基类“CustomBase”。我们不是测试一般的继承连接,而是测试子类是否具有可调用的“magic_attribute”方法。

第 2 步 生成两个类,“DerivedWithMagic”和“DerivedWithoutMagic”。前者有 'magic_attribute' 方法,而后者没有。

第 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 程序。

以上是在Python中,__subclasscheck__和__subclasshook__是两个特殊方法的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:tutorialspoint。如有侵权,请联系admin@php.cn删除
Python vs. C:了解关键差异Python vs. C:了解关键差异Apr 21, 2025 am 12:18 AM

Python和C 各有优势,选择应基于项目需求。1)Python适合快速开发和数据处理,因其简洁语法和动态类型。2)C 适用于高性能和系统编程,因其静态类型和手动内存管理。

Python vs.C:您的项目选择哪种语言?Python vs.C:您的项目选择哪种语言?Apr 21, 2025 am 12:17 AM

选择Python还是C 取决于项目需求:1)如果需要快速开发、数据处理和原型设计,选择Python;2)如果需要高性能、低延迟和接近硬件的控制,选择C 。

达到python目标:每天2小时的力量达到python目标:每天2小时的力量Apr 20, 2025 am 12:21 AM

通过每天投入2小时的Python学习,可以有效提升编程技能。1.学习新知识:阅读文档或观看教程。2.实践:编写代码和完成练习。3.复习:巩固所学内容。4.项目实践:应用所学于实际项目中。这样的结构化学习计划能帮助你系统掌握Python并实现职业目标。

最大化2小时:有效的Python学习策略最大化2小时:有效的Python学习策略Apr 20, 2025 am 12:20 AM

在两小时内高效学习Python的方法包括:1.回顾基础知识,确保熟悉Python的安装和基本语法;2.理解Python的核心概念,如变量、列表、函数等;3.通过使用示例掌握基本和高级用法;4.学习常见错误与调试技巧;5.应用性能优化与最佳实践,如使用列表推导式和遵循PEP8风格指南。

在Python和C之间进行选择:适合您的语言在Python和C之间进行选择:适合您的语言Apr 20, 2025 am 12:20 AM

Python适合初学者和数据科学,C 适用于系统编程和游戏开发。1.Python简洁易用,适用于数据科学和Web开发。2.C 提供高性能和控制力,适用于游戏开发和系统编程。选择应基于项目需求和个人兴趣。

Python与C:编程语言的比较分析Python与C:编程语言的比较分析Apr 20, 2025 am 12:14 AM

Python更适合数据科学和快速开发,C 更适合高性能和系统编程。1.Python语法简洁,易于学习,适用于数据处理和科学计算。2.C 语法复杂,但性能优越,常用于游戏开发和系统编程。

每天2小时:Python学习的潜力每天2小时:Python学习的潜力Apr 20, 2025 am 12:14 AM

每天投入两小时学习Python是可行的。1.学习新知识:用一小时学习新概念,如列表和字典。2.实践和练习:用一小时进行编程练习,如编写小程序。通过合理规划和坚持不懈,你可以在短时间内掌握Python的核心概念。

Python与C:学习曲线和易用性Python与C:学习曲线和易用性Apr 19, 2025 am 12:20 AM

Python更易学且易用,C 则更强大但复杂。1.Python语法简洁,适合初学者,动态类型和自动内存管理使其易用,但可能导致运行时错误。2.C 提供低级控制和高级特性,适合高性能应用,但学习门槛高,需手动管理内存和类型安全。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)