gpt4 book ai didi

python - 虚子类有什么用?

转载 作者:太空狗 更新时间:2023-10-30 02:07:22 26 4
gpt4 key购买 nike

class AnimalMeta(type):
def __instancecheck__(cls, instance):
return cls.__subclasscheck__(type(instance))

def __subclasscheck__(cls, sub):
return (hasattr(sub, 'eat') and callable(sub.eat) and
hasattr(sub, 'sleep') and callable(sub.sleep))


class Animal(object):
__metaclass__ = AnimalMeta
pass


class Dog(object):
def eat(self):
print "eat"
def sleep(self):
print "sleep"


dog = Dog()
dog.eat()

print isinstance(dog, Animal)
print issubclass(dog, Animal)

输出:

eat
True
True

我正在尝试理解 python 虚拟子类,示例如上所示。实例虚拟子类根本不需要实现抽象方法。

虚子类的实际用例是什么?在我看来,虚拟子类的工作方式类似于鸭子类型和对象继承。

Duck类型--虚子类--对象继承

最佳答案

我读了Interfaces in Python: Protocols and ABCs这让我有了更好的理解。我们在 Python 中输入鸭子:

If it talks and walks like a duck, then it is a duck.

但是,飞机 都可以fly()。但它们不是一回事。因此,我们需要定义一个接口(interface)来区分它们。 (Python 没有interface 关键字,所以我们实际上使用的是抽象类)

让我举个例子:

我们的程序中有 DuckMyPlane。他们都实现了 fly() 方法。现在我们要从机库中选择一架飞机,让一些人登机,飞往另一个城市。显然,我们不能把人放在Duck上,所以我们定义了一个接口(interface),叫做(实际上是一个抽象类)Plane。我们让 MyPlane 成为 Plane 的子类。

一切正常。当我们想要选择一个平面时,我们检查它是否是 Plane 的子类。然而,波音公司开发了一个包,其中有一个Boeing747Plane。我们购买了这架飞机(from boeing_airplanes import Boeing747Plane),但它未被识别为飞机。它确实有一个 fly() 方法,但它不是从我们的 Plane 类继承的,所以我们的 Python 解释器不会将它识别为一个平面。

好消息是 Python 是一种灵活的语言。感谢 ABCMetaregister 方法,在我们执行 Plane.register(Boeing747Plane) 之后,Boeing747Plane平面 现在。我们可以像使用我们自己 build 的 Plane 一样使用第三方的 Boeing747Plane。万岁!

所以你看,当我们想从第三方包中创建一个类作为我们自己的抽象类的子类时,就会使用虚拟类。我们希望它实现我们的接口(interface),但是我们不能改变它的代码,所以我们明确地告诉解释器“它实现了我们的接口(interface),请把它当作我们自己类的子类”。我认为通常我们不想使用它,但是当您需要时,请谨慎使用它。正如 Luca Cappelletti 所说,这是 Python 允许的众多灵 active 之一,遵循其“我们在这里是成年人”的理念。

关于python - 虚子类有什么用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51666120/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com