简体   繁体   中英

What does "ABC" class do?

I wrote a class that inherits another class:

class ValueSum(SubQuery):
    output = IntegerField()

And pycharm is showing the following warning:

Class ValueSum must implement all abstract methods

Then I alt+enter to add ABC to superclass. And my warning is gone. I have several questions:

  • Should I always do this when writing a sub-class?

  • What is the difference between manually implementing all the methods vs just using ABC ?

  • Does ABC add something to my code?

SubQuery is an abstract base class (per the abc module ) with one or more abstract methods that you did not override. By adding ABC to the list of base classes, you defined ValueSum itself to be an abstract base class. That means you aren't forced to override the methods, but it also means you cannot instantiate ValueSum itself.

PyCharm is warning you ahead of time that you need to implement the abstract methods inherited from SubQuery ; if you don't, you would get an error from Python when you actually tried to instantiate ValueSum .


As to what inheriting from ABC does , the answer is... not much. It's a convenience for setting the metaclass. The following are equivalent:

class Foo(metaclass=abc.ABCMeta):
    ...

and

class Foo(abc.ABC):
    ...

The metaclass modifies __new__ so that every attempt to create an instance of your class checks that the class has implemented all methods decorated with @abstractmethod in a parent class.

That's the main point of abstract classes following to Object Oriented Programming (OOP). Classes, which inherit from an abstract class, need to implement all of the abstract methods. They don't need to, if they are abstract themselves. Those abstract methods are like method signatures of interfaces and don't have any implementation inside them. Therefor you cannot create a non-abtract class without impementing all the abstract methods. ABC is just a helper class to create new abstract classes by deriving from it. Here you can read more about abstract classes in Python: https://docs.python.org/3/library/abc.html

Based on your observation you mark ValueSum to be abstract. This means, that all subclasses of ValueSum need to implement the abstract methods of ValueSum and all its abstract superclasses, including SubQuery .

I write class that abstracts from some class.

No. You wrote a class, which inherits from another.

Should I always do this when I writing sub class?

No. Only if you want the class to be abstract.

What is the difference between manually implementing all the methods vs just using ABC

In this case you are forwarding the implementation to all subclasses of ValueSum . Not using ABC will force you to implement the abstract methods inside of ValueSum .

Does ABC add something to my code?

No. In any case, not more than using other classes / inheritation.

The 'Abstract Base classes" or abc.ABC is a helper class

https://docs.python.org/3/library/abc.html

Here's a snippet of why they exist:

The collections module has some concrete classes that derive from ABCs; these can, of course, be further derived. In addition, the collections.abc submodule has some ABCs that can be used to test whether a class or instance provides a particular interface, for example, if it is hashable or if it is a mapping.

A good example here: https://pymotw.com/2/abc/ | https://pymotw.com/3/abc/

From pymotw:

Forgetting to set the metaclass properly means the concrete implementations do not have their APIs enforced. To make it easier to set up the abstract class properly, a base class is provided that sets the metaclass automatically.

abc_abc_base.py
import abc


class PluginBase(abc.ABC):

    @abc.abstractmethod
    def load(self, input):
        """Retrieve data from the input source
        and return an object.
        """

    @abc.abstractmethod
    def save(self, output, data):
        """Save the data object to the output."""


class SubclassImplementation(PluginBase):

    def load(self, input):
        return input.read()

    def save(self, output, data):
        return output.write(data)


if __name__ == '__main__':
    print('Subclass:', issubclass(SubclassImplementation,
                                  PluginBase))
    print('Instance:', isinstance(SubclassImplementation(),
                                  PluginBase))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM