4

I'm trying to pick up Python for a project, and I'm a bit confused about how to use abstraction and classes. (I'm not a very experienced programmer, so apologies for the basic level of this question.) I come from a Java/Ocaml background, and what I've been trying to do is as follows: I have abstract classes for a graph and a graphadvanced (a graph with some more fancy methods), that look something like this

class AbstractGraph: 
   def method1(self): 
      raise NotImplementedError
   ...

class AbstractAdvanced:
   def method2(self):
      raise NotImplementedError 
   ... 

I then have an implementation of a graph:

class Graph(AbstractGraph):
   def method1(self):
      * actual code * 

Now my question is: can I do something like this?

class Advanced(AbstractAdvanced, AbstractGraph):
   def method2(self):
      *actual code, using the methods from AbstractGraph*

In other words, how can I define the methods of Advanced abstractly in terms of the methods of AbstractGraph, and then somehow pass Graph into a constructor to get an instance of Advanced that uses Advanced's definitions with Graph's implementation?

In terms of Ocaml, I'm trying to treat AbstractAdvanced and AbstractGraph as module types, but I've played around a little with python and I'm not sure how to get this to work.

3
  • 1
    fix the formatting, you click the code tab when you're editing Commented Apr 15, 2012 at 15:07
  • 2
    In python, there's usually no need for stuff like this. Just write the actual code. Commented Apr 15, 2012 at 15:15
  • As I understand it, python does not use the strict concept of interfaces and typechecks like e.g. Java. Through Duck-Typing it does not really make sense. So you just do it. Cou could enforce it by isinstance() calls for your parameter, but that wont really give you the static typing you are used to. Python is a dynamically typed language. Commented Apr 15, 2012 at 16:38

1 Answer 1

1

If you want to create abstract base classes, you can, but they are of limited utility. It's more normal to start your class hierarchy (after inheriting from object, or some other third-party class) with concrete classes.

If you want to create a class that pieces together various classes that partially some protocol, then just inherit from your implementing classes:

#Always inherit from object, or some subtype thereof, unless you want your code to behave differently in python 2 and python 3

class AbstractGraph(object): 
   def method1(self): 
      raise NotImplementedError

class Graph(AbstractGraph):
   def method1(self):
      * actual code * 

class GraphToo(AbstractGraph):
   def method1(self):
      * actual code * 

class AbstractAdvanced(AbstractGraph):
   def method2(self):
      raise NotImplementedError 

class Advanced(Graph,AbstractAdvanced):
   def method2(self):
      *actual code, using the methods from Graph*

# order of classes in the inheritance list matters - it will affect the method resolution order
class AdvancedToo(GraphToo, Advanced): pass
Sign up to request clarification or add additional context in comments.

9 Comments

I guess the point is that I would like to be able to potentially pass in different Graph implementations that have the same method names, without having to rewrite essentially identical code each time. Is there no way to do this?
@Tony Yes, there is, as I explained: you inherit from those classes.
@Tony- indeed, you wouldn't have to rewrite any of the "actual code" lines. Inheriting the Graph class would get all those methods for you.
Sorry for being slow, but I'm afraid I still don't quite understand. Suppose I wrote two classes Graph1 and Graph2, saying Graph1 implementing graphs with undirected, unweighted edges and Graph2 implementing graphs with directed, weighted edges. I then want to define an Advanced class which will do things like BFS, DFS, etc. (things that make sense for both implementations). From what you wrote above, it seems like I would have to write Advanced1(AbstractAdvanced, Graph1) and Advanced2(AbstractAdvanced, Graph2) and write essentially the same code for method2 for each.
@Tony No, you would create a ConcreteAdvanced class to hold your method2 implementation, then inherit from both ConcreteAdvanced and whichever of your graph classes. Thus, there would be no code duplication.
|

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.