在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中文网其他相关文章!

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

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

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

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

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

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

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

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


热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

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

热门文章

热工具

Dreamweaver CS6
视觉化网页开发工具

WebStorm Mac版
好用的JavaScript开发工具

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

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

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)