7

So, I am trying to define an abstract base class with couple of variables which I want to to make it mandatory to have for any class which "inherits" this base class.. So, something like:

class AbstractBaseClass(object):
   foo = NotImplemented
   bar = NotImplemented

Now,

class ConcreteClass(AbstractBaseClass):
    # here I want the developer to force create the class variables foo and bar:
    def __init__(self...):
        self.foo = 'foo'
        self.bar = 'bar'

This should throw error:

class ConcreteClass(AbstractBaseClass):
    # here I want the developer to force create the class variables foo and bar:
    def __init__(self...):
        self.foo = 'foo'
        #error because bar is missing??

I maybe using the wrong terminology.. but basically, I want every developer who is "implementing" the above class to force to define these variables??

4
  • 1
    check out docs.python.org/2/library/abc.html Commented May 12, 2015 at 20:51
  • 1
    abc provides for abstract properties (which might be applicable here) and abstract methods, not general instance variables. Commented May 12, 2015 at 20:53
  • 1
    But why to check those value at init stage, perhaps the user will define them later. So I think you should set them to None in the Abstract Base Class. And when you need it in some of your abcd methods. If there are again at None, then you'll throw an exception... Commented May 12, 2015 at 20:58
  • 3
    Trust is pretty fundamental to Python programming, with duck typing, lack of private variables, and so on. Even if you could force the developer to initialize the class with those variables, what would stop them from deleting those variables later? Commented May 12, 2015 at 21:03

2 Answers 2

5

Update: abc.abstractproperty has been deprecated in Python 3.3. Use property with abc.abstractmethod instead as shown here.

import abc

class AbstractBaseClass(object):

    __metaclass__ = abc.ABCMeta

    @abc.abstractproperty
    def foo(self):
        pass

    @abc.abstractproperty
    def bar(self):
        pass

class ConcreteClass(AbstractBaseClass):

    def __init__(self, foo, bar):
        self._foo = foo
        self._bar = bar

    @property
    def foo(self):
        return self._foo

    @foo.setter
    def foo(self, value):
        self._foo = value

    @property
    def bar(self):
        return self._bar

    @bar.setter
    def bar(self, value):
        self._bar = value
Sign up to request clarification or add additional context in comments.

2 Comments

You may want to demonstrate how to create a read-write property in addition to a read-only property.
Added setters to make the properties writable
2
class AbstractBaseClass(object):
    def __init__(self):
        assert hasattr(self, 'foo')
        assert hasattr(self, 'bar')

3 Comments

That's easily defeated by simply overriding and not calling AbstractBaseClass.__init__.
Also, assertions can be turned off.
Anything in python could be overridden... If you don't call the base class init you are responsible of what you are doing.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.