I use Python 3.5 and my project structure is like this:
Project/
App/
myApp.py
Libraries/
myLibA.py
myLibB.py
I want to import myLibA.py
in myApp.py
If I simply write from Libraries import myLibA
I end up with this error :
ImportError: No module named Libraries.
I found the Q/A Importing files from different folder in Python , from which I adapted my own solution, adding this at the beginning of myApp.py
in order to add my Project
folder to the Python Path :
import sys
sys.path.insert(0, sys.path[0] + "..")
This worked well on Windows, but when I run myApp.py
from the same project on OSX (10.9) I see the same error message, my module is not found.
To reproduce my issue it's very simple. Just fill the Python files like this :
myApp.py :
import sys
sys.path.insert(0, sys.path[0] + "..")
from Libraries import myLibA
if __name__ == '__main__':
myLibA.print_hello()
myLibA.py :
def print_hello():
print("Hello")
I don't understand why the Python Path method doesn't work here. Anyway, I'm looking for a solution that keeps the Python file compatible with Windows and that is contained in the sources (in the Python files). I've seen a few console hooks but I'm not satisfied with that because I want to be able to clone the project on any OSX/Windows PC with Python 3.5, and just run myApp.py. I'm looking for a solution that doesn't involve any library not natively present in Python 3.5.
Is there another way to achieve this ?
(If not, is it because it is somehow not pythonic to organize a project like this? As a C developer I might have the wrong approach)
Add __init__.py
to your Libraries
directory. That file can be empty, and it magically turns the Libraries
directory into a package . Now:
import sys
import os.path
libdir = os.path.dirname(__file__)
sys.path.append(os.path.split(libdir)[0])
from Libraries import myLibA
if __name__ == '__main__':
myLibA.print_hello()
The __file__
special variable gives the filename of the current script. os.path.dirname()
gives the directory it resides in, and os.path.split(libdir)[0]
gives its parent directory. This should work wherever the script is called from.
I am using append
rather than insert
. It is generally advised that user directories are searched last, and also append
is more efficient than insert
in the C Python implementation.
You should have __init__.py
inside every folder that you want to import. Also a common project structure for a python project is this:
Project/
Libraries/ <-- this will contain app specific code (Libraries)
__init__.py
myLibA.py
myLibB.py
main.py
Where main.py will contain the entry code of you app, just like C's main(), for example
from Libraries import myLibA
if __name__ == '__main__':
myLibA.print_hello()
No need to tinker with sys.path in runtime.
This Question is somewhat similar. My favourite answer suggests a project structure like this in your case:
Project/
myApp.py
Libraries/
__init__.py
myLibA.py
myLibB.py
With the library code in myLibA.py
unchanged the app code and import would look like this:
from Libraries import myLibA
if __name__ == "__main__":
myLibA.print_hello()
Edit 1:
When the requested folder structure is necessary, this change to the myApp.py
file:
import sys
import os
sys.path.append(os.path.abspath(".."))
works too.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.