如何导入给定相对路径的Python模块?
例如,如果dirFoo包含Foo.py和dirBar,而dirBar包含Bar.py,我如何将Bar.py导入Foo.py?
下面是一个视觉表示:
dirFoo\
Foo.py
dirBar\
Bar.py
Foo希望包含Bar,但重组文件夹层次结构不是一个选项。
如何导入给定相对路径的Python模块?
例如,如果dirFoo包含Foo.py和dirBar,而dirBar包含Bar.py,我如何将Bar.py导入Foo.py?
下面是一个视觉表示:
dirFoo\
Foo.py
dirBar\
Bar.py
Foo希望包含Bar,但重组文件夹层次结构不是一个选项。
当前回答
添加__init__.py文件:
dirFoo\
Foo.py
dirBar\
__init__.py
Bar.py
然后将以下代码添加到Foo.py的开头:
import sys
sys.path.append('dirBar')
import Bar
其他回答
不修改脚本的最简单方法是设置PYTHONPATH环境变量。因为sys.path是从以下位置初始化的:
包含输入脚本的目录(或当前目录)。PYTHONPATH(目录名列表,与语法作为外壳变量PATH)。依赖于安装的默认值。
只需运行:
export PYTHONPATH=/absolute/path/to/your/module
sys.path将包含上述路径,如下所示:
print sys.path
['', '/absolute/path/to/your/module', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/gst-0.10', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', '/usr/lib/python2.7/dist-packages/ubuntuone-client', '/usr/lib/python2.7/dist-packages/ubuntuone-control-panel', '/usr/lib/python2.7/dist-packages/ubuntuone-couch', '/usr/lib/python2.7/dist-packages/ubuntuone-installer', '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol']
确保dirBar具有__init__.py文件——这会将一个目录放入Python包中。
只需使用:从Desktop.filename导入一些内容
例子:
给定目录中的文件名为test.py用户/用户/桌面,并将导入所有内容。
代码:
from Desktop.test import *
但请确保在该目录中创建一个名为“__init__.py”的空文件
假设您的两个目录都是真正的Python包(其中确实包含__init__.py文件),这里有一个相对于脚本位置包含模块的安全解决方案。
我假设您想这样做,因为您需要在脚本中包含一组模块。我在一些产品的生产中使用了这一点,并在许多特殊场景中工作,例如:从另一个目录调用或使用python执行的脚本,而不是打开新的解释器。
import os, sys, inspect
# realpath() will make your script run, even if you symlink it :)
cmd_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0]))
if cmd_folder not in sys.path:
sys.path.insert(0, cmd_folder)
# Use this if you want to include modules from a subfolder
cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"subfolder")))
if cmd_subfolder not in sys.path:
sys.path.insert(0, cmd_subfolder)
# Info:
# cmd_folder = os.path.dirname(os.path.abspath(__file__)) # DO NOT USE __file__ !!!
# __file__ fails if the script is called in different ways on Windows.
# __file__ fails if someone does os.chdir() before.
# sys.argv[0] also fails, because it doesn't not always contains the path.
另外,这种方法允许您强制Python使用您的模块,而不是安装在系统上的模块。
警告我真的不知道当当前模块在蛋文件中时会发生什么。它可能也会失败。
称我过于谨慎,但我喜欢让我的更便携,因为假设文件总是在每台计算机上的同一位置是不安全的。就我个人而言,我让代码先查找文件路径。我使用Linux,所以我的看起来像这样:
import os, sys
from subprocess import Popen, PIPE
try:
path = Popen("find / -name 'file' -type f", shell=True, stdout=PIPE).stdout.read().splitlines()[0]
if not sys.path.__contains__(path):
sys.path.append(path)
except IndexError:
raise RuntimeError("You must have FILE to run this program!")
当然,除非你打算把这些包装在一起。但如果是这样的话,你实际上不需要两个单独的文件。