1

I fully acknowledge that Python and Java are different programming languages and should be used differently. That said, "Program to an interface, not to an implementation" is good language-agnostic programming advice.

Say I have some DAO interface in Java:

public interface DataDao {

  Object load();
  void update();
  void delete();
}

Programming to that interface allows me to persist data in files while I'm prototyping, swap that out for a database as I get further along, etc. rather painlessly as long as I honor the contract of the DataDao.

What's the Pythonic approach/version (if any) to programming to a contract to keep your classes orthogonal, modular, and enable frictionless implementation changes?

4
  • 1
    Er... you just do it, plain and simple? You write Python code that works with some interface and does not make assumptions about implementation details. What exactly do you expect to be different?
    – user7043
    Commented Feb 23, 2014 at 23:57
  • I may well be looking at the world too much so from a a strongly-typed, object-oriented perspective, but it seems like there should be some way to do this cleanly in Python if desired and have the language or interpreter provide some level of enforcement.
    – rpmartz
    Commented Feb 24, 2014 at 0:02
  • The way to do it in Python, if you really want to, is to write method stubs and have them raise NotImplementedErrors. I personally think that's silly.
    – user16764
    Commented Feb 24, 2014 at 0:30
  • @RyanM There's no way to get enforcement at compile time. At runtime logc's solution works if you're interested in explicitly querying for the interface, but if all you plan on doing is aborting with some error then you've gained nothing; you would've gotten that for free when your code tries to use non-existent methods. If this sort of thing matters to you then it's better not to use a dynamically typed language.
    – Doval
    Commented Feb 25, 2014 at 12:27

1 Answer 1

2

You can use abstract base classes, if you really want to. Another option would be to use the mock library while developing and especially while testing.

An abstract base class is like a mix of a Java interface with a Java abstract class: it cannot be instantiated directly, subclasses need to implement all of its methods, but the parent methods may have an implementation that is callable via super.

Here is an example for an abstract DAO, with concrete file-backed and database-backed subclasses:

import abc

class DataAccess(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def load(self):
        pass

    @abc.abstractmethod
    def update(self):
        pass

    @abc.abstractmethod
    def delete(self):
        pass

class FileDataAccess(DataAccess):

    def load(self):
        with open(self.filename, 'r') as infile:
            contents = infile.read()
        return contents

    def update(self):
        pass

    def delete(self):
        pass

class DbDataAccess(DataAccess):

    def load(self):
        pass

    def update(self):
        pass

    def delete(self):
        pass

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.