Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uninstantiable superclass

So, I'm writing a module for connecting to external account providers (Twitter, Facebook etc) and I have a superclass that is useless on its own, but contains generic methods that need to be invoked by the subclasses for persisting auth tokens, getting auth tokens and deauthorizing the provider. My question is, is there a way to make it uninstantiable or should I follow the consenting adults rule and just let anyone who uses it make mistakes as they see fit? Other than a docstring is there a good way to denote that someone shouldn't use this superclass on its own?

like image 440
tiny_mouse Avatar asked Jun 06 '11 18:06

tiny_mouse


2 Answers

I'm seconding Sven Marnach's edit: I think you should follow the "consenting adults" rule and mention in the docstring that the class is not meant to be instantiated.

The key phrase in your question is "I have a superclass that is useless on its own." It won't invoke cthulhu when instantiated; it won't cause some kind of catastrophic, hard-to-debug failure somewhere else in your program; it will just be a minor waste of time. That's not worth crippling the class for, I think.

like image 92
senderle Avatar answered Sep 21 '22 11:09

senderle


class NoInstantiation:    # "class NoInstantiation(object):" in Python 2.2+ or whatever
    def __new__(cls):
        "This class is not meant to be instantiated, so __new__ returns None."
        return None

This won't stop people from overriding that functionality if they want to, but it should be a fairly decent method of preventing accidental instantiation. If someone does accidentally call it, well, they can't say you didn't warn them.

EDIT: If you really wanted to be nice, you could also print a warning to stderr in __new__() about it or even throw an exception.

EDIT 2: If you go the exception route, you may want to raise the exception within the __init__() method of the superclass instead, as users will likely be overriding __init__() in their subclasses anyway.

EDIT 3: There's also the option of setting __new__ or __init__ equal to None, though the resultant error wouldn't be very informative.

like image 38
JAB Avatar answered Sep 20 '22 11:09

JAB