0

I'm having a problem with calling a function between two python file. I have this file, fileone.py. This is the main file it runs continuously, then when the if statement becomes true it will do a task then after that it will call the main() function in the other file, filetwo.py. Then I'm using break to stop the loop: (fileone.py)

import filetwo

foo = "sample"

def main():
    while True:
        if foo == "sample":
            #Some task here
            print("HELLO")
            filetwo.main()
            break
main()

And this is the other file, filetwo.py. It has a main() function, fileone.py will call this function to do some task, then after doing the task it will call the main() function again in the fileone.py: (filetwo.py)

import fileone

foo = True

def main():
    if foo == True:
        #Some task here
        print("WORLD")
        fileone.main()

But, I'm getting this kind of error. AttributeError: module 'filetwo' has no attribute 'main'. I don't know if my approach of calling the file functions is good or is there a much better way to do it. I tried to use os.system to run/call the python file but I've read in some articles here that it is much better to call it in a functional way.

N.Omugs
  • 321
  • 4
  • 17
  • 1
    Please add your code as formatted text, not as a screenshot. – Klaus D. Jun 04 '19 at 02:43
  • @KlausD. Copy sir, I'm sorry sir. – N.Omugs Jun 04 '19 at 02:45
  • 3
    You have a circular import there, where two files import each other. That's never going to work. You're going to have exactly the kinds of problems you're having. What are you actually trying to accomplish here by doing that? – kindall Jun 04 '19 at 02:46
  • @kindall haha :p my first answer was on the circular importing problem haha – U13-Forward Jun 04 '19 at 02:47
  • @kindall actually, my first file, `fileone.py` is something like a scheduler. When a certain time hit the schedule it will run the `filetwo.py`, which is the script to do some task. Then after finishing the task, I'm trying to run the scheduler again which is my `fileone.py`. something like that. – N.Omugs Jun 04 '19 at 02:55
  • How about creating `filethree.py` that controls `fileone.py` and `filetwo.py`? – Chin Hong Tan Jun 04 '19 at 02:58
  • Possible duplicate of [Python circular importing?](https://stackoverflow.com/questions/22187279/python-circular-importing) – knh190 Jun 04 '19 at 03:07
  • 1
    See this specific answer can help: https://stackoverflow.com/a/22187343/3340588 – knh190 Jun 04 '19 at 03:08
  • So what is the best way to call/run again the `fileone.py` after running the task in `filetwo.py`? Thanks for the ideas. – N.Omugs Jun 04 '19 at 03:16
  • 1
    The calling function doesn't stop running when it calls another function. It just waits for the return. This applies whether it is in the same file or not. – Adam Burke Jun 04 '19 at 03:28

2 Answers2

0

One way to solve the problem is to use if __name__ == "__main__" in file one. Note that since while loop repeats forever you will eventually have a RecursionError after printing out so many "HELLO" and "WORLD".

import filetwo

foo = "sample"

def main():
    while True:
        if foo == "sample":
            #Some task here
            print("HELLO")
            filetwo.main()
            break

if __name__ == '__main__':
   main()

File two is unchanged and below

import fileone

foo = True

def main():
    if foo == True:
        #Some task here
        print("WORLD")
        fileone.main()

Miracle
  • 23
  • 4
0

There doesn't seem to be any need for filetwo to recurse back into fileone. Just have fileone call filetwo and continue the loop when it returns.

fileone.py:

import filetwo

foo = "sample"

def main():
    while True:
        if foo == "sample":
            #Some task here
            print("HELLO")
            filetwo.main()
            print("(back in main loop, fileone.foo is {0!r} and filetwo.foo is {1!r})".format(foo, filetwo.foo))

main()

Then in filetwo.py:

foo = True

def main():
    if foo == True:
        #Some task here
        print("WORLD")
        return  # Just to be explicit

It's not clear what you expect foo to be. There are actually two objects called foo, one in the fileone scope with the value "sample", and another in the filetwo scope with the value True. If you would like to share a variable between the two modules, perhaps pass it in the call (or, less ideally, make it global).

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • The `foo` variables are different. In my main program I really need to stop the while loop because Im having a problem while performing the task in the `filetwo.py` so I need to `break` it. Then after performing the task it will return to `fileone.py`. – N.Omugs Jun 04 '19 at 06:17
  • Well then put the `break` back. The main point here really is that there is no need, nor any sane reason, for `filetwo` to recursively call `fileone`. Just return from `filetwo` and let `fileone` continue from where it left off. – tripleee Jun 04 '19 at 06:30
  • so in your code, how can I return back to the while loop in my `fileone.py`? – N.Omugs Jun 04 '19 at 06:38
  • `return` returns from a function. Falling off the end does the same thing implictly. – tripleee Jun 04 '19 at 06:39