1

I have a problem with importing modules, I using Spyder 3.7 as editor it's look like doesn't imported : First module test.py :

def func():
    print('func() is tes.py')
print("top level in test.py")
if __name__=='__main__':
    print('test.py is being run directly')
else:
    print('test.py is being imported into another module')

Second as test2.py

import test

print ('top level in test2.py')
test.func()


if __name__=='__main__':
    print('test.py is being run directly')
else:
    print('test.py is being imported into another module')

Both files are registered in the same folder when I execute the test2.py I get this error

module 'test' has no attribute 'func'

I read the issue 1 and issue 2 but doesn't help me please any idea and thank you.

  • 2
    You might want to name your module something else, since [`test`](https://docs.python.org/3/library/test.html) is a standard Python module. It could be that you are importing that instead of your own `test.py` file. – khelwood Jun 13 '20 at 18:14
  • Yes @khelwood it's the reason. I changed the name of both files to one and two it executes normally. Thank you – Mohamed Hasnaoui Jun 13 '20 at 18:21
  • Great. I'll post it as an answer. – khelwood Jun 13 '20 at 18:23
  • I ran your code (`python test2.py`) and it worked. No errors. Could not reproduce. – tdelaney Jun 13 '20 at 18:48

3 Answers3

2

You might want to name your module something else, since test is a standard Python module, and apparently you are importing that instead of your own test.py file.

khelwood
  • 55,782
  • 14
  • 81
  • 108
  • 1
    Yes is it. Thank you – Mohamed Hasnaoui Jun 13 '20 at 18:24
  • Its a very good idea to avoid module names from the standard libraries (or popular libraries - numpy.py for instance would be a bad name). But python puts the script's directory at the front of the python path and the user's `test.py` would mask the standard `test.py`. I don't see how this fixed the problem. Its possible to have different importers that could explain this but the standard python implementation on my linux machine loads the local `test.py`. – tdelaney Jun 13 '20 at 18:44
0

Add an empty __init__.py while running from IDE. This will help ide identify it as a python package. If you run it through terminal it shall execute when you run python test2.py.

➜ cat test2.py 
import test

print ('top level in test2.py')
test.func()


if __name__=='__main__':
    print('test.py is being run directly')
else:
    print('test.py is being imported into another module')

# code execution
➜ python test2.py 
top level in test.py
test.py is being imported into another module
top level in test2.py
func() is tes.py
test.py is being run directly
sandeshdaundkar
  • 883
  • 1
  • 7
  • 14
  • Maybe there is some IDE where this helps, but not in most cases. Python adds the script's directory to the module path so any python files or package subdirectories in that path are recognized. But the directory itself is not a package and an `__init__.py` in that directory is not loaded. – tdelaney Jun 13 '20 at 18:33
0

Importing in python can be tricky to understand.

An easy fix is to add the current directory to sys.path in the following way:

import os, sys
path = os.path.abspath(__file__)
dirname = os.path.dirname(path)
if dirname not in sys.path:
    sys.path.insert(0, dirname)

Than the python interpreter will be able to find the second file on the same folder.

If you want to be able to import the whole directory as a module than you can just modify the previous with:

dirname = os.path.dirname(os.path.dirname(path))

Edit: Updated with suggestion of tdelaney

piertoni
  • 1,933
  • 1
  • 18
  • 30
  • Try printing `sys.path` before this trick. On my standard linux python, the script's path has already been prepended to the path by python itself. This just adds it a second time. – tdelaney Jun 13 '20 at 18:46