andydavies andydavies -4 years ago 148
Python Question

Why is it important to prevent instantiation of classes that are theoretically abstract?

I have two data structures,

Frontier
(a queue) and
Explored
(a set). I want to implement a custom
__contains__
method that they share:

class Custom_Structure:
def __contains__(self, item):
# TODO

class Frontier(Custom_Structure):
def __init__(self):
self.queue = Queue.Queue()

class Explored(Custom_Structure):
def __init__(self):
self.set = set()


I understand the theory of inheritance and abstract classes (or at least, I think I do!). It seems that making
Custom_Structure
an abstract class is appropriate here, because I don't intend it to be instantiated; it is only there so that
Frontier
and
Explored
can share the
__contains__
method. I don't need any abstract methods, but that's ok because I've read that an abstract class doesn't necessarily need abstract methods.

If I was doing this in C# I'd just add the
abstract
keyword, and I wouldn't be asking this question. But in Python (2.7) it seems I need to do something like this:

from abc import ABCMeta

class Custom_Structure:
__metaclass__ = ABCMeta
...


Ok, it's still not that big a deal, but it's not very readable, and it just feels like overkill with not much benefit. I'm tempted to just leave my code as it is.

So my question is: Why bother going to the trouble of making
Custom_Structure
abstract?
(So what if someone instantiates the base class?)

I've found the following questions already but they don't quite answer the question:

Why use Abstract Base Classes in Python? The answer here doesn't seem to apply because I don't have any abstract methods, so there is no contract between the base class and subclasses.

What is the main advantage of making a class abstract Same

Abstract class with no abstract methods This has the answer 'to prevent instantiation', but why is that such a problem?

What's the point in having an abstract class with no abstract methods? Same

Why use an abstract class without abstract methods? Same. I understand the theoretical concept of why it shouldn't be instantiated, but what's the big deal practically?

I've read various questions and answers about the theory behind abstract classes - my question is not about what they are and how they work (although if I'm mistaken please tell me), it's more 'what is the benefit' in this simple case?

Answer Source

Interesting question. Let me begin by saying that the very fact that this piece of ugliness is the way abstract classes are created in python2...

from abc import ABCMeta

class Custom_Structure:
    __metaclass__ = ABCMeta

... already indicates that the Python Dictators didn't think marking classes as explicitly abstract was all that important.

That said, making a class abstract is a useful way of adding metadata to the code. It's a way for the author of a class to communicate with future users of a module.

What's being said? Two things:

  1. An abstract class is incomplete, and should not be instantiated. An instance of this class has no concrete meaning, because the definition is partial. It lacks the full set of information necessary to make the object work.

  2. An abstract method is the missing piece of the definition. By making a method abstract, you're stating that for the class to make sense, this specific part of the full description must be provided. Not only that, but by providing an interface you're conveying the expected behavior of the missing piece, whatever the internal details end up being.

Of course, all of this can be the case in practice without any additional specification for the class or its methods, but then inheritors end up guessing how to use the object, or have to read the documentation in detail.

If you instantiate an implicitly abstract class, sooner or later an error will occur. Could end up producing a NotImplementedError, or a KeyError when something's missing. This mistake is easy to make, and will arise down the road when trying to use the functionality of the object.

If you try to instantiate an explicitly abstract class, the error is immediate. No dice are thrown, and the problem is not postponed to whenever the class is used in one way or another. A missing implementation for abstract method won't cause an error when and if the method is used, but immediately when the coding mistake is made.

Summing up, making a class and some of its methods explicitly abstract makes the reality of the code adhere to the documentation. It moves the responsibility of knowing the rules from the inexperienced user to the author. It's a way of having the language runtime enforce in practice the theoretical rules and constraints of usage.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download