Bob
Bob

Reputation: 39

Most pythonic way to call dependant methods

I have a class with few methods - each one is setting some internal state, and usually requires some other method to be called first, to prepare stage. Typical invocation goes like this:

c = MyMysteryClass()
c.connectToServer()
c.downloadData()
c.computeResults()

In some cases only connectToServer() and downloadData() will be called (or even just connectToServer() alone).

The question is: how should those methods behave when they are called in wrong order (or, in other words, when the internal state is not yet ready for their task)?

I see two solutions:

Currently I'm using second approach, as it allows me to write less code (I can just write c.computeResults() and know that two other methods will be called if necessary). Plus, when I call them multiple times, I don't have to keep track of what was already called and so I avoid multiple reconnecting or downloading.

On the other hand, first approach seems more predictable from the caller perspective, and possibly less error prone.

And of course, there is a possibility for a hybrid solution: throw and exception, and add another layer of methods with internal state detection and proper calling of previous ones. But that seems to be a bit of an overkill.

Your suggestions?

Upvotes: 1

Views: 75

Answers (3)

Sean Fujiwara
Sean Fujiwara

Reputation: 4546

If it's possible, you should make the dependencies explicit.

For your example:

c = MyMysteryClass()
connection = c.connectToServer()
data = c.downloadData(connection)
results = c.computeResults(data)

This way, even if you don't know how the library works, there's only one order the methods could be called in.

Upvotes: 0

makansij
makansij

Reputation: 9875

You should write exceptions. It is good programming practice to write Exceptions to make your code easier to understand for the following reasons:

  1. What you are describe fits the literal description of "exception" -- it is an exception to normal proceedings.
  2. If you build in some kind of work around, you will likely have "spaghetti code" = BAD.
  3. When you, or someone else goes back and reads this code later, it will be difficult to understand if you do not provide the hint that it is an exception to have these methods executed out of order.

Here's a good source: http://jeffknupp.com/blog/2013/02/06/write-cleaner-python-use-exceptions/

As my CS professor always said "Good programmers can write code that computers can read, but great programmers write code that humans and computers can read".

I hope this helps.

Upvotes: 1

Andrew Gorcester
Andrew Gorcester

Reputation: 19983

They should throw an exception. As said in the Zen of Python: Explicit is better than implicit. And, for that matter, Errors should never pass silently. Unless explicitly silenced. If the methods are called out of order that's a programmer's mistake, and you shouldn't try to fix that by guessing what they mean. You might accidentally cover up an oversight in a way that looks like it works, but is not actually an accurate reflection of the programmer's intent. (That programmer may be future you.)

If these methods are usually called immediately one after another, you could consider collating them by adding a new method that simply calls them all in a row. That way you can use that method and not have to worry about getting it wrong.

Note that classes that handle internal state in this way are sometimes called for but are often not, in fact, necessary. Depending on your use case and the needs of the rest of your application, you may be better off doing this with functions and actually passing connection objects, etc. from one method to another, rather than using a class to store internal state. See for instance Stop Writing Classes. This is just something to consider and not an imperative; plenty of reasonable people disagree with the theory behind Stop Writing Classes.

Upvotes: 1

Related Questions