Opened a Server Python but Can Not Run Again
How to Fix ModuleNotFoundError and ImportError
Do proper module imports and make your life easier
tl;dr
- Use absolute imports
- Append your project'due south root directory to
PYTHONPATH— In whatever environment you wish to run your Python application such every bit Docker, vagrant or your virtual surroundings i.eastward. in bin/activate, run (or e.g. add tobin/activatein case y'all are using virtualenv) the below control:
export PYTHONPATH="${PYTHONPATH}:/path/to/your/projection/" - *avert using
sys.path.append("/path/to/your/project/")
Module imports can certainly frustrate people and specially those who are adequately new to Python. Since I keep seeing relevant questions on StackOverflow on a daily footing, I decided to write an commodity hither on Medium to attempt and draw how import works behind the scenes and what arroyo you need to follow in order to practice your life easier.
Terminology
First, allow's start by defining some useful terms that will help you lot sympathize the concepts described in this article.
- A python module is a single file with a .py extension.
- A python package is a folder that contains at to the lowest degree one python module. For python2, a package requires a __init__.py file
- A python parcel can contain whatsoever number of nested sub-packages, i.due east. packages that comprise other packages down the hierarchy of the projection structure.
- imports are useful when a module needs to utilise some piece of functionality (east.g. a office or a grade) written in another module (of the same or a unlike package or sub-package)
For example, consider the following project construction:
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py Projection myproject contains two packages, mypackage and anotherpackage each of which contains a number of python modules, while the latter too contains a sub-parcel called mysubpackage which in turn contains an boosted python module.
How does module import piece of work behind the scenes?
At present let'south assume that in your current module, you wish to import another module as shown below:
import a Python will execute the above argument in two steps:
- Locate, load and initialise (if required) the requested module
- Define necessary names in the local namespace and corresponding telescopic
At present Python interpreter is going to follow the next steps in an attempt to resolve a .
Footstep one: sys.modules lookup
Initially, Python volition try to search for the module'south name insys.modules , which is a dictionary that maps module names to modules which have already been loaded. If the proper name is resolved successfully (which means that another module has already loaded it) will be so be made available to the local namespace otherwise, jump into pace 2.
Step 2: Python Standard Library lookup
Python Standard Library contains born modules (written in C) that provide access to system functionality such as file I/O that would otherwise be inaccessible to Python programmers, besides as modules written in Python that provide standardized solutions for many problems that occur in everyday programming. Some of these modules are explicitly designed to encourage and raise the portability of Python programs by abstracting abroad platform-specifics into platform-neutral APIs.
If the proper name couldn't be found in sys.modules then Python is going to search for it in Python Standard Library. Again, if the name is resolved then it will be defined in the local namespace otherwise step 3 needs to be followed.
Step 3: sys.path lookup
Now if the module'south proper name was not plant either in sys.modules nor in standard library, Python will finally try to resolve information technology nether sys.path. And this is the point where things tin certainly go wrong. I believe most Python programmes are quite familiar with ModuleNotFoundError
import a ModuleNotFoundError: No module named 'a'
or ImportError :
from . import a ImportError: cannot import proper noun 'a'
Absolute vs Relative imports
In accented imports, we specify the explicit path starting from the project's root directory. In our example
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py this means that if we would similar to import module a in module b we would have to specify
import mypackage.a Other valid examples are the following imports:
# in module a.py
import anotherpackage.mysubpackage.d # in module b
import anotherpackage.c
Now on the other hand, in relative imports we specify the path to the module relatively to the location of the current module. A few examples in our example could be:
# in module a.py
from ..anotherpackage import b
from ..anotherpackage.b import another_function # in module b
from . import c
from .c import my_function
I'd personally discourage the use of relative imports every bit they are not equally readable as accented imports and PEP-eight suggests the same besides. In some rare cases, yous might accept to use relative imports in lodge to avoid unnecessarily long paths. For example,
from package_a.sub_b.sub_c.sub_d.module_d import my_function How to fix ModuleNotFoundError and ImportError?
Now we're upwards to speed with how the basic import statement is executed and what is the difference between absolute and relative imports we tin now go ahead and talk over what to practice when your Python application fails with either ModuleNotFoundError or ImportError .
In most of the cases, either of the errors occur due to the fact that Python is unable to resolve the module'south proper noun in sys.path . Recall that when you phone call import a if the module'due south name was found neither in sys.modules nor in standard library, Python will try to resolve it in sys.path . Besides, when you use from syntax (e.yard. from mypackage import a ), Python will offset attempt to find and load the module. When information technology fails to practice so, Python will throw ModuleNotFoundError for the first case or ImportError for the 2nd case.
If that's the instance and recalling our example below,
└── myproject
├── mypackage
│ ├── a.py
└── anotherpackage
├── b.py
├── c.py
└── mysubpackage
└── d.py - first brand sure you are using accented imports
- consign the project's root directory to
PYTHONPATH
Most modernistic Python IDEs will do the trick automatically but if this is not the instance, I am pretty sure there will exist such selection where you'll exist able to ascertain the PYTHONPATH for your Python application (at least PyCharm).
If you are running your Python application in any other environs such as Docker, Vagrant or inside your virutal surroundings y'all can run the beneath command in your bash:
consign PYTHONPATH="${PYTHONPATH}:/path/to/your/projection/" # * For Windows
set PYTHONPATH=%PYTHONPATH%;C:\path\to\your\project\
and now since your project'south root directory has been appended to PYTHONPATH your accented imports should piece of work similar a amuse.
sys.path.suspend(/path/to/your/project/ tin perchance practise the play a joke on besides, but it'due south definitely not a good practise.
Conclusion
If yous are new to Python, import modules tin get a nightmare especially if you need to deal with a complex projection construction. If you follow the two-stride rule — i.eastward utilize absolute imports and append your projection's root directory to PYTHONPATH — and so you shouldn't really worry almost module imports in the futurity.
If y'all are new to Python, I would highly recommended getting a re-create of Learning Python book on Amazon.
Become a member and read every story on Medium. Your membership fee directly supports me and other writers you read. You'll also get full access to every story on Medium.
randallyoureforthim68.blogspot.com
Source: https://towardsdatascience.com/how-to-fix-modulenotfounderror-and-importerror-248ce5b69b1c
0 Response to "Opened a Server Python but Can Not Run Again"
Post a Comment