使用sys.path和os.path问题导入Python模块

时间:2017-11-13 05:23:27

标签: python python-import

我花了一些时间研究这个,我无法解决这个问题。

我在自己的目录home / program / core / main.py

中运行一个程序

在main.py中,我尝试导入一个名为my_module.py的模块,该模块位于不同的目录中,比如home / program / modules / my_module.py

在main.py中,这是我附加到sys.path的方式,因此程序可以在任何人的机器上运行(希望如此)。

import os.path
import sys

# This should give the path to home/program
sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__), '..'))
# Which it does when checking with
print os.path.join(os.path.abspath(os.path.dirname(__file__), '..')

# So now sys.path knows the location of where modules directory is, it should work right?

import modules.my_module # <----RAISES ImportError WHY?

但是,如果我只是这样做:

sys.path.append('home/program/modules')
import my_module

一切正常。但这并不理想,因为它现在取决于程序必须存在于家庭/程序之下的事实。

2 个答案:

答案 0 :(得分:1)

这是因为modules不是有效的python包,可能是因为它不包含任何__init__.py文件(你无法遍历import的目录,但没有标记为__init__.py

因此,要么添加空的__init__.py文件,要么只添加modules的路径,这样您的第一个代码段就相当于第二个代码段:

sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__), '..','modules'))
import my_module

请注意,您还可以使用高级导入功能提供模块的完整路径来导入模块:How to import a module given the full path?

答案 1 :(得分:0)

尽管可以找到答案here,但为了方便和完整,这里是一个快速的解决方案:

import importlib

dirname, basename = os.path.split(pyfilepath) # pyfilepath: /my/path/mymodule.py
sys.path.append(dirname) # only directories should be added to PYTHONPATH
module_name = os.path.splitext(basename)[0] # /my/path/mymodule.py --> mymodule
module = importlib.import_module(module_name) # name space of defined module (otherwise we would literally look for "module_name")

现在您可以直接使用导入模块的命名空间,如下所示:

a = module.myvar
b = module.myfunc(a)