一、背景
在python构建的工程中,A.py 可能要使用 B.py 文件中的函数、或者类、或者变量,如果这两个文件在同一个目录下,只需要在 A.py 中使用 import B 即可,但如果不在同一目录下,则这种方法不可用,将工程下的所有文件放在一个目录下又会显得混乱,那么如何解决这个问题?
如下图所示,需要在 func_exam.py 中调用 models 文件夹下的 test_module.py 文件中的类。
二、sys.path.append(folder_path)
解决方法之一是使用sys.append,该方法将输入的路径 folder_path 添加到文件查找的路径,因此在 folder_path 路径下的所有文件都可以import。
- import sys
import sys
import os
# 获取当前.py文件的绝对路径
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# 将当前.py文件目录下的 models 目录添加到系统路径
# 因此 models 目录下的 .py 文件可以在本语句之后 import
sys.path.append(os.path.join(BASE_DIR , 'models'))
import pointnet2_cls_ssg
这种方法的缺点在于必须在 sys.path.append 函数之后 import,否则会报错,而且即使正确地 import 了这个文件,那条 import 语句会被打上红色波浪线(运行时不会报错),对强迫症不友好。
三、importlib.import_module(model_name)
这种方法可以在函数中调用其他文件夹中的 .py 文件,不用使用 import,因此可以设置一个判断条件,根据满足条件与否调用不同的 .py 文件,不需要像 import 一样写死在文件开头。
- import importlib
import importlib
def test_importlib():
# 导入 models 目录下的 test_module.py 文件中的内容
import_model = importlib.import_module('models.test_module')
amodel = import_model.test_module()
amodel.print_func()
由以上代码可知,转到下一级目录是用 'models.test_module' 而不是 'models/test_module'
也可以将 models 文件夹的路径添加到系统路径,这样直接在函数参数输入模型名即可,无需使用相对路径,且不会出现红色波浪线。实例代码如下:
import os
import sys
import importlib
# 获取当前 .py 文件的绝对路径
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# 将当前路径下的 models 目录添加到系统目录
sys.path.append(os.path.join(BASE_DIR, 'models'))
def test_importlib():
# 因为之前已经将 models 目录添加到系统目录,此时直接导入 test_module 即可
import_model = importlib.import_module('test_module')
amodel = import_model.test_module()
amodel.print_func()
四、pip install e.
使用该方法需要写一个 setup.py 文件,之后使用命令行转到该文件的目录,运行 pip install e.命令,之后即可直接在项目文件中 import 其它文件夹中的 .py 文件。
setup.py 文件实例如下:
from setuptools import setup
setup(name='models',# 随便写,在piplist里会显示的名字
packages=['models'],# 在其它文件里import的名字
package_dir={'models': 'models'},# 需要引用的其它文件的目录