Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the usage of a virtual subclass?

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)

Output:

eat
True
True

I am trying to understand python virtual subclass, example shows as above. instance a virtual subclass doesn't require implement abstract method at all.

What's the real use cases of virtual subclass? it seems to me the virtual subclass works like something in the middle of duck type and object inherit.

Duck type -- virtual subclass -- object inheritance

like image 428
weiwang Avatar asked Aug 03 '18 05:08

weiwang


People also ask

What is virtual subclass?

PreviousNext. In Python, it does need to be an actual subclass of a parent class to be considered a subclass-instead Virtual subclasses allow one class to be treated as a subclass of another even though there is no direct inheritance relationship between them.

What is the use of virtual base class?

Virtual base classes are used in virtual inheritance in a way of preventing multiple “instances” of a given class appearing in an inheritance hierarchy when using multiple inheritances.

Why do we use virtual base class in C++?

Virtual base class in C++ Virtual classes are primarily used during multiple inheritance. To avoid, multiple instances of the same class being taken to the same class which later causes ambiguity, virtual classes are used.

What is virtual class in inheritance?

Virtual inheritance is a C++ technique that ensures only one copy of a base class's member variables are inherited by grandchild derived classes.


1 Answers

I read Interfaces in Python: Protocols and ABCs and it gives me a better understanding. We have duck typing in Python:

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

However, a Bird and Aeroplane both can fly(). But they are not the same thing. Hence, we need to define an interface to distinguish them from each other. (Python does not have an interface keyword, so we are actually using abstract classes)

Let's me show an example:

We have Duck and MyPlane in our program. Both of them implemented fly() method. Now we want to choose a plane from the hangar, get some people on board, and fly to another city. Apparently, we cannot put people onto a Duck, so we define an interface called (actually, an abstract class) Plane. And we let MyPlane to subclass Plane.

Everything works fine. When we want to choose a plane, we check if it subclasses Plane. However, the Boeing company developed a package, which has a Boeing747Plane. We bought the plane (from boeing_airplanes import Boeing747Plane), but it is not recognized as a plane. It does have a fly() method, but it's not inherited from our Plane class so our Python interpreter won't recognize it as a plane.

The good news is that Python is a flexible language. Thanks for register method of ABCMeta, after we do Plane.register(Boeing747Plane), Boeing747Plane is a subclass of Plane now. We can use third-party Boeing747Plane like our own built Plane. Hooray!

So you see, virtual classes are used when we want to make a class from a third-party package to be a subclass of our own abstract class. We want it to implement our interface, but we cannot change its code, so we tell the interpreter explicitly "it implemented our interface, please treat it as the subclass of our own class". I think normally we wouldn't want to use it, but when you need to, use it cautiously. As Luca Cappelletti said, this is one of many flexibilities that Python allows for, following its philosophy of "we are adults here".

like image 124
F. Chan Avatar answered Oct 17 '22 20:10

F. Chan