Python 模块导入 sys.path 和 os.path 问题
Python module importing with sys.path and os.path issue
我花了一些时间研究这个,但我就是无法在脑海中解决这个问题。
我运行一个程序在它自己的目录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
一切正常。但这并不理想,因为它现在取决于程序必须存在于 home/program.
下的事实
那是因为 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?
尽管可以找到答案 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)
我花了一些时间研究这个,但我就是无法在脑海中解决这个问题。
我运行一个程序在它自己的目录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
一切正常。但这并不理想,因为它现在取决于程序必须存在于 home/program.
下的事实那是因为 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?
尽管可以找到答案 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)