3

I have a module with a main function that runs a loop while a flag is true. In the loop, there is a call to a function defined in another module that check a conditions and should stop the main loop if it's True.

The code is:

main.py

import other

isRunning = True
def shutdown():
    global isRunning
    isRunning = False

def main():
    while isRunning:
        # some logic here
        other.check()

if __name__ == '__main__':
    main()

other.py

import main

def check():
    someCondition = #some logic to check the condition
    if someCondition:
        main.shutdown()

The code is run launching the main.py file.

The issue is that when other.check() is called in the loop, the main.shutdown() function is called but the main loop keeps running. In the main loop the isRunning variable is always True, but I was expecting it to become False after being set in the main.shutdown() function. Why is this happening? What am I missing?

I could refactor the code to mange the exit from the loop in a smarter way, but I am interested to know if there is a solution keeping this kind of code structure.

1
  • You probably need a global isRunning statement in main(). Commented Mar 11, 2016 at 9:11

2 Answers 2

4

The issue has to do with the main.py file being loaded twice. It first gets loaded as __main__ when you run it as a script. It also gets imported by other.py as its regular name main.

The two copies are completely separate from each other, and have separate global variables! When other.check calls main.shutdown to modify the isRunning global variable, it only changes the main.isRunning version, not __main__.isRunning. The main function is checking __main__.isRunning which doesn't ever get changed.

There are several ways you can fix this. The best is probably to get rid of your circular import in some way. While circular importing can work OK in Python, it's often a symptom of bad design. It's a very bad idea to use it with any module that may be run as a script.

Sign up to request clarification or add additional context in comments.

1 Comment

I know that this design is bad, I was just doing some quick tests to check some ideas and I stepped in this issue. I did not know what you described, it will be very useful. Thanks.
3

Try this:

import other


def main():
    while other.run():
        # some logic here
        other.check()

if __name__ == '__main__':
    main()

other.py

import main

isRunning = True
def run():
    return isRunning

def check():
    global isRunning
    someCondition = #some logic to check the condition
    if someCondition:
        isRunning = False

If I was you I would use objects and classes..., global methods and variables are not "debug and maintenance friendly"

Comments

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.