---
title: "Python ModuleNotFoundError与ImportError排查"
author: "Perrin Yong"
author_profile: https://www.pystone.net/profile/
published_by: "Perrin Yong"
canonical: https://www.pystone.net/notes/python-modulenotfounderror-import-debug/
type: note
content_role: unspecified
visibility: public
id_stability: rename-stable
source_path: "10-计算机、信息技术与工程/03-软件工程与质量保障/CI-CD与质量保障/CI-CD工具链/Python ModuleNotFoundError与ImportError排查.md"
content_hash: 5346b3730b02d9cfbc1a4c46b162854c85f84ef279ff838fdffd6366e3e92c90
knowledge_version: 224c990773de.5fa8af6e39fa
site_commit: 224c990773de166d23a886306577dd90379529ce
notes_commit: 5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a
---
# Python ModuleNotFoundError与ImportError排查

> 创建时间：2021/5/18 17:17

## 【Python】How to Fix ModuleNotFoundError and Im
  * 【Python】How to Fix ModuleNotFoundError and ImportError
    * Terminology
    * How does module import work behind the scenes?
      * Step 1: sys.modules lookup
      * Step 2: Python Standard Library lookup
      * Step 3: sys.path lookup
    * Absolute vs Relative imports
      * absolute imports
      * relative imports
    * Resolution
      * Use IDE
      * Other cases
        * 方法一：命令行
        * 方法二：python scripts
    * Ref

## Terminology

**python module** \- a single file with a .py extension.
**python package** \- a folder that contains at least one python module.

>   * For python2, a package requires a **init**.py file
>
>   * A python package can contain any number of nested **sub-packages**
>
>

```csharp
string str1 = String.Empty;
string str2 = String.Empty;

str2 = String.Intern(sb.ToString());

if((object)str1==(object)str2)
    Console.WriteLine(&quot;The strings are equal.&quot;);
else
    Console.WriteLine(&quot;The strings are not equal.&quot;);

```

> Project myproject contains two packages, mypackage and anotherpackage each of which contains a number of python modules, while the latter also contains a sub-package called mysubpackage which in turn contains an additional python module.

## How does module import work behind the scenes?

```csharp
string str1 = String.Empty;
string str2 = String.Empty;

str2 = String.Intern(sb.ToString());

if((object)str1==(object)str2)
    Console.WriteLine(&quot;The strings are equal.&quot;);
else
    Console.WriteLine(&quot;The strings are not equal.&quot;);

```

Python will execute the above statement in two steps:

  * Locate, load and initialise (if required) the requested module

  * Define necessary names in the local namespace and corresponding scope

Now Python interpreter is going to follow the next steps in an attempt to **resolve a** .

### Step 1: sys.modules lookup

Initially, Python will try to search for the module’s name in **sys.modules** , which is a dictionary that maps module names to modules which have already been loaded. If the name is resolved successfully (which means that another module has already loaded) it will be then be made available to the local namespace otherwise, jump into step 2.

![Alt text](/media/a13631e2187aef2a4b70.png)

```csharp
string str1 = String.Empty;
string str2 = String.Empty;

str2 = String.Intern(sb.ToString());

if((object)str1==(object)str2)
    Console.WriteLine(&quot;The strings are equal.&quot;);
else
    Console.WriteLine(&quot;The strings are not equal.&quot;);

```

### Step 2: Python Standard Library lookup

> Python Standard Library contains built-in modules (written in C) that provide access to system functionality such as file I/O that would otherwise be inaccessible to Python programmers, as well 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 enhance the portability of Python programs by abstracting away platform-specifics into platform-neutral APIs.

If the 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’s name was not found either in sys.modules nor in standard library, Python will finally attempt to resolve it under **sys.path**.

![Alt text](/media/e3a6d8657ccb22a2fc3d.png)

## Absolute vs Relative imports

We discourage the use of relative imports as they are not as readable as absolute imports

```csharp
string str1 = String.Empty;
string str2 = String.Empty;

str2 = String.Intern(sb.ToString());

if((object)str1==(object)str2)
    Console.WriteLine(&quot;The strings are equal.&quot;);
else
    Console.WriteLine(&quot;The strings are not equal.&quot;);

```

### absolute imports

```csharp
string str1 = String.Empty;
string str2 = String.Empty;

str2 = String.Intern(sb.ToString());

if((object)str1==(object)str2)
    Console.WriteLine(&quot;The strings are equal.&quot;);
else
    Console.WriteLine(&quot;The strings are not equal.&quot;);

```

### relative imports

```csharp
string str1 = String.Empty;
string str2 = String.Empty;

str2 = String.Intern(sb.ToString());

if((object)str1==(object)str2)
    Console.WriteLine(&quot;The strings are equal.&quot;);
else
    Console.WriteLine(&quot;The strings are not equal.&quot;);

```

## Resolution

核心原则：

  * use absolute imports

  * append your project’s root directory to PYTHONPATH

本质是：

  * 给sys.path中添加路径，使得import时能够找到相应的module。

  * 给sys.modules中添加item

### Use IDE

Most modern Python **IDEs** will do the trick automatically but if this is not the case, I am pretty sure there will be such option where you’ll be able to define the PYTHONPATH for your Python application

### Other cases

以下两种方法效果相同。

#### 方法一：命令行

If you are running your Python application in any other environment such as **Docker** , **Vagrant** or **inside your virutal environment** you can run the below command in your bash:

```csharp
string str1 = String.Empty;
string str2 = String.Empty;

str2 = String.Intern(sb.ToString());

if((object)str1==(object)str2)
    Console.WriteLine(&quot;The strings are equal.&quot;);
else
    Console.WriteLine(&quot;The strings are not equal.&quot;);

```

上述命令会将相应的path添加到 **sys.path** 当中。

#### 方法二：python scripts

Add this code in your python scripts:

```csharp
string str1 = String.Empty;
string str2 = String.Empty;

str2 = String.Intern(sb.ToString());

if((object)str1==(object)str2)
    Console.WriteLine(&quot;The strings are equal.&quot;);
else
    Console.WriteLine(&quot;The strings are not equal.&quot;);

```

## Ref

<https://towardsdatascience.com/how-to-fix-modulenotfounderror-and-importerror-248ce5b69b1c>
