Question

first I should say I don't know if the topic is good enough or not, but explaining my problem in one line is really hard.

After that, I'm gonna explain you the whole event;

I'm writing a program in python in which I have a class with some methods and one of these methods(method1), runs another method(method2) of the class in a loop over a list of configuration data and in method2 I call some other methods of the class. The code is something like this:

class myClass():
    def method1(self):
        for member in some_list:
            method2(member)

    def method2(self, member):
        do something with the member
        self.method3()
        self.method4()
        self.method5()
        ...

In method2 there are some situations that I want to stop method2 from inside methods. I mean sometimes I want to stop method2 while I'm in the method3 or method4 for example.

I don't want to use assert, because it stops the whole program and I just want to skip this special member and continue the loop in method1. In other words, some members of the list make some situations in which we can't continue method2 and we should stop there and start the process of method2 for the next member of the list.

I now that I can return True and False values and check it to decide if I want to stop by the return keyword or not, but I don't want to use this approach. What I actually want is to write a method that in those situations, I call it and the method stops the method2 execution and go back to the first loop in method1 to select another member. I can write an example:

def method3(self):
    do something 
    if some_special_situation:
        method_stop()
    else:
        continue execution

def method_stop():
    do something to stop the method which is calling it
    and the method that the first method is called there
    I mean if method2 is calling method3 and method3 is calling method_stop
    method_stop should stop both method2 and method3

I don't know how clear is this question, but if you want any explanation, ask me please. I will appreciate any help.

Was it helpful?

Solution

Using exceptions would be the most straightforward approach if the methods other than method1 are private (otherwise external callers would have to handle the Exception):

class MyClass():
    class ContinueException(Exception):
        pass

    def method1(self, members):
        for member in members:
            try:
                print "in method1 with ", member
                self.method2(member)
            except MyClass.ContinueException:
                pass

    def method2(self, member):
        print "->in method2 with ", member
        self.method3(member)
        self.method4(member)

    def method3(self, member):
        print "--->in method3 with ", member
        if member % 2 == 0:
            raise MyClass.ContinueException()

    def method4(self, member):
        print "----->in method4 with ", member

When member is even, an exception will be raised in method3 so method4 won't be called:

>>> c = MyClass()
>>> c.method1([1,2,3,4])
in method1 with  1
->in method2 with  1
--->in method3 with  1
----->in method4 with  1
in method1 with  2
->in method2 with  2
--->in method3 with  2
in method1 with  3
->in method2 with  3
--->in method3 with  3
----->in method4 with  3
in method1 with  4
->in method2 with  4
--->in method3 with  4
>>>

OTHER TIPS

Just throw an exception, and catch it in method1. Which BTW is what assert does, it throws AssertionError and you can catch that. It just ends the program when it falls all the way through to the interpreter.

method1():
    method_names = ["method1","method2",...]
    for name in method_names:
        if !getattr(self, name)():
            return False
    #more code

method2():
    #epic code goes here
    if bad_stuff_happens:
        return False
    #epic code goes here
    return True
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top