📜  Python - 在目录外导入模块

📅  最后修改于: 2022-05-13 01:55:22.142000             🧑  作者: Mango

Python - 在目录外导入模块

模块只是一个Python .py 文件,我们可以从中使用另一个文件中的函数、类和变量。要在另一个文件中使用这些东西,我们需要先在该文件中导入该模块,然后才能使用它们。如果模块与文件在同一目录下,则模块可以存在于不同的目录中,我们可以使用语法 import module_name 直接导入它。但是如果它存在于不同的目录中,我们就不能直接导入它。在本文中,我们将讨论从目录外部导入模块的各种方法。

我们的目录树如下:

D :\projects\base
|__main.py   
|__app:
      |__modules
           |___mod.py

我们在 D:\projects 中有一个名为“base”的文件夹,在基本文件夹中我们有一个名为 app 的文件夹。 base 包含 main.py,我们将在其中导入模块,app 包含另一个名为 modules 的文件夹,其中包含 mod.py,这是需要导入的模块。

为了更好的解释,我们将尽可能简化两个文件的代码:



模块.py:

Python
# defining a function hello()
def hello():
    
    # printing the string 'hello geeks!'
    print('hello geeks!')


Python
# importing the sys module
import sys         
  
# appending the directory of mod.py 
# in the sys.path list
sys.path.append('D:/projects/base/app/modules')        
  
# now we can import mod
import mod    
  
# calling the hello function of mod.py
mod.hello()


Python
# importing the sys module
import sys        
  
# inserting the mod.py directory at 
# position 1 in sys.path
sys.path.insert(1, 'D:/projects/base/app/modules')        
  
# importing the module mod.py
import mod    
  
# calling the function hello() of mod.py
mod.hello()


Python
# importing the module
import app.modules.mod         
  
# calling the hello function of the module
app.modules.mod.hello()


Python
# importing the importlib.util module
import importlib.util        
  
# passing the file name and path as argument
spec = importlib.util.spec_from_file_location(
  "mod", "D:/projects/base/app/modules/mod.py")    
  
# importing the module as foo 
foo = importlib.util.module_from_spec(spec)        
spec.loader.exec_module(foo)
  
# calling the hello function of mod.py
foo.hello()


现在我们将导入模块 mod.py 并使用多种方法在 main.py 中调用其函数hello。

方法一:使用 sys.path.append()

模块 sys 的 sys.path 变量包含Python将在其中搜索要导入的模块的所有目录的列表。我们可以直接调用这个方法来查看它包含的目录。因此,为了在 main.py 中导入 mod.py,我们将在 sys.path 中附加 mod.py 的路径,以便导入时Python在其目录中搜索 mod.py 并找到它以成功导入它。此方法的代码将是:

Python

# importing the sys module
import sys         
  
# appending the directory of mod.py 
# in the sys.path list
sys.path.append('D:/projects/base/app/modules')        
  
# now we can import mod
import mod    
  
# calling the hello function of mod.py
mod.hello()

输出:

hello geeks!

方法 2:使用 sys.path.insert()。

正如我们已经讨论过的, sys.path 包含将搜索模块的所有目录的列表。更好的方法是在位置 1 插入模块的目录,以便以更高的优先级加载它,这反过来有助于避免一些名称冲突。此方法的 main.py 代码将是:

Python



# importing the sys module
import sys        
  
# inserting the mod.py directory at 
# position 1 in sys.path
sys.path.insert(1, 'D:/projects/base/app/modules')        
  
# importing the module mod.py
import mod    
  
# calling the function hello() of mod.py
mod.hello()

输出:

hello geeks!

方法 3:使用 __init__.py

我们也可以通过首先将其存在的目录转换为Python包来导入模块。要将目录转换为Python包,我们必须在该目录中包含一个文件 __init__.py ,该文件可以留空。当我们添加文件 __init__.py 时,我们告诉Python该目录是一个包。因此,在创建 __init__.py 后,目录树将如下所示:

D :\projects\base
|__main.py 
|__app:
|      |__modules
|          |___mod.py
|          |___init__.py
|__main.py

我们在 import 语句中调用模块的方式是我们从 app 文件夹转到 mod 文件,并用“.”分隔每个路径变量。 .现在要从此方法导入 main.py 中的 mod.py,main.py 中的代码将是:

Python

# importing the module
import app.modules.mod         
  
# calling the hello function of the module
app.modules.mod.hello()

输出:

hello geeks!

方法四:使用导入库

我们还可以使用导入库从外部目录导入模块。为此,我们首先必须导入 importlib.util 模块。然后调用 importlib.util.spec_from_file_location() 方法,该方法接受 2 个参数 file_name 和 file_path 并返回一个值,该值将与 importlib.util.module_from_spec() 方法一起使用以导入具有特定名称的模块。然后我们可以使用这个特定的名称来调用模块的函数、类、变量。

Python

# importing the importlib.util module
import importlib.util        
  
# passing the file name and path as argument
spec = importlib.util.spec_from_file_location(
  "mod", "D:/projects/base/app/modules/mod.py")    
  
# importing the module as foo 
foo = importlib.util.module_from_spec(spec)        
spec.loader.exec_module(foo)
  
# calling the hello function of mod.py
foo.hello()

输出:

hello geeks!