0

I am new to Python. I was playing with "Importing modules" in python and came to this 'thing' :

This is my main.py

import test

test.hello()

This is my test.py

import main

def hello():
    print("hello")

It results in

Traceback (most recent call last):
  File "main.py", line 1, in <module>
    import test
  File "/home/imtiazirtiaz/Desktop/Python/test/test.py", line 1, in <module>
    import main
  File "/home/imtiazirtiaz/Desktop/Python/test/main.py", line 3, in <module>
    test.hello()
AttributeError: module 'test' has no attribute 'hello'

So I thought the function was not defined. So I changed the test.py

def hello():
    print("hello")

import main

But now when I run main.py, the output is:

hello
hello

Why does it prints hello twice?

And running the test.py says:

hello

Please help me showing what is going on. How does cross importing modules work in python?

I am using python 3.6

Imtiaz Kabir
  • 119
  • 4
  • 8
  • See: https://stackoverflow.com/questions/7336802/how-to-avoid-circular-imports-in-python, https://stackoverflow.com/questions/22187279/python-circular-importing, https://stackoverflow.com/questions/744373/circular-or-cyclic-imports-in-python – Sayandip Dutta Dec 27 '19 at 12:14

2 Answers2

1

you are getting hello twice because in test.py file you have imported main.py file which contain a import statement and a function call to the hello()

remove import main from test.py every thing will work fine.

Abhishek-Saini
  • 733
  • 7
  • 11
  • by what u mean 'fine'? I did not mention a 'problem'. I wanted to know why this was happening.If your answer is - "don't import module like this" - then how does it answer the question named - "How does cross importing modules work in python"? – Imtiaz Kabir Dec 28 '19 at 15:14
0

The solution is to get rid of the line import main in test.py. Here's why:

In the first instance you have:

  1. Run main.py
  2. The first step is to import test.
  3. Now Python is told to import main again.
  4. Since we're already in the process of import test, the next step is test.hello()
  5. But def hello(): ... has not yet been evaluated, so there's an error.

In the second case you have:

  1. Run main.py
  2. Import test
  3. Now we define hello() so test.hello evaluates to the hello() function.
  4. Import main again
  5. We've already imported test
  6. So now run test.hello() which is the hello() function.
  7. Now we've finally finished the first import of test from step 2.
  8. Finally run test.hello()

So test.hello() runs twice.


You're touching here on the issue of circular dependencies. For now my advice is not to import anything you don't need, and don't execute anything at the top-level of a file of package.

Best practice if you want a file to run is to do it like this:

main.py

import test

def main():
    test.hello()

if __name__ == '__main__':
    # what to do if the file is called 
    main()

This way, if you later want to call the main function but not as a file, it is very easy to do so...

import main
main.main()
blueteeth
  • 3,330
  • 1
  • 13
  • 23