views:

160

answers:

3

What is the shortest / most elegant way to implement the following Scala code with an abstract attribute in Python?

abstract class Controller {

    val path: String

}

A subclass of Controller is enforced to define "path" by the Scala compiler. A subclass would look like this:

class MyController extends Controller {

    override val path = "/home"

}
A: 

Bastien Léonard's answer mentions the abstract base class module and Brendan Abel's answer deals with non-implemented attributes raising errors. To ensure that the class is not implemented outside of the module, you could prefix the base name with an underscore which denotes it as private to the module (i.e. it is not imported).

i.e.

class _Controller(object):
    path = '' # There are better ways to declare attributes - see other answers

class MyController(_Controller):
    path = '/Home'
Brendan
is it possible to raise some error if the subclass does not redefine the attribute? It would be easy for methods, but how about attributes?
Mario
Wouldn't it be better to leave out the path declaration in `_Controller` class? Duck Typing wouldn't take effect if there is already a (invalid) value. Otherwise at some point, where I need the `path` field to be defined, there would be no error because there is already a value.
deamon
@Mario - yes, Brendan Abel's answer gives a good way to do this
Brendan
+4  A: 

Have a look at the abc (Abtract Base Class) module: http://docs.python.org/library/abc.html

However, in my opinion the simplest and most common solution is to raise an exception when an instance of the base class is created, or when its property is accessed.

Bastien Léonard
+7  A: 

Python has a built-in exception for this, though you won't encounter the exception until runtime.

class Base(object):
    @property
    def path(self):
        raise NotImplementedError


class SubClass(Base):
    path = 'blah'
Brendan Abel
Specifically, you won't encounter the exception until the attrtibute is accessed, in which case you would have got an AttributeError anyway.
Ben James
I think that raising a `NotImplementedError` is more explicit and therefore probably better than leaving it to an `AttributeError`.
blokeley
Also you can add a message such "Can't instantiate abstract class Base" when raising an exception yourself.
Bastien Léonard