Python中的相对导入

Python中的相对导入,python,python-2.7,module,python-import,Python,Python 2.7,Module,Python Import,我有以下目录结构,我是python新手。在文件夹bin中,我有一个文件“script.py”,我想从代码包中导入“module.py”。我在stackoverflow上看到了许多解决这个问题的方法,包括修改sys path或提供完整的路径名。有没有办法用一个相对有效的import语句来导入它们,而不是指定完整路径 project/ bin/ script.py code/ module.py

我有以下目录结构,我是python新手。在文件夹bin中,我有一个文件“script.py”,我想从代码包中导入“module.py”。我在stackoverflow上看到了许多解决这个问题的方法,包括修改sys path或提供完整的路径名。有没有办法用一个相对有效的import语句来导入它们,而不是指定完整路径

 project/

         bin/
             script.py

         code/
             module.py
             __init__.py

为了确保
bin/script.py
可以在不配置环境的情况下运行,请从代码导入模块行将此序言添加到
script.py
之前的
(
发件人):


while
循环支持从
bin/其他一些目录运行它/../script.py

要确保
bin/script.py
可以在不配置环境的情况下运行,请将此序言添加到
script.py
之前的代码导入模块的
行(
发件人):


while
循环支持从
bin/some other directory/../script.py

运行它。虽然正确,但我认为“动态地将我的当前目录添加到路径”是一个肮脏、肮脏的黑客行为

项目中添加一个(可能为空)
\uuuu init\uuuu.py
。然后将包含
项目
路径的
.pth
文件添加到
站点包
目录中。然后:

来自project.code导入模块

在我看来,这有两个好处:

1) 如果进行重构,只需更改project.code
行中的
,并避免弄乱其他内容

2) 您的代码没有什么特别之处——它的行为与您通过PyPi安装的任何其他软件包完全相同

将项目目录添加到PYTHONPATH可能看起来很混乱,但我认为这是一个比任何替代方案都干净得多的解决方案。就我个人而言,我已经使用
.pth
文件将所有python代码所在的父目录添加到我的PYTHONPATH中,因此我可以像处理第三方库一样处理我编写的所有代码


我不认为把PYTHONPATH弄得乱七八糟有什么问题,因为只有带有
\uuu init\uuuu.py
的文件夹才是可导入的

虽然正确,但我认为“动态地将我的当前目录添加到路径”是一个肮脏的、肮脏的黑客行为

项目中添加一个(可能为空)
\uuuu init\uuuu.py
。然后将包含
项目
路径的
.pth
文件添加到
站点包
目录中。然后:

来自project.code导入模块

在我看来,这有两个好处:

1) 如果进行重构,只需更改project.code
行中的
,并避免弄乱其他内容

2) 您的代码没有什么特别之处——它的行为与您通过PyPi安装的任何其他软件包完全相同

将项目目录添加到PYTHONPATH可能看起来很混乱,但我认为这是一个比任何替代方案都干净得多的解决方案。就我个人而言,我已经使用
.pth
文件将所有python代码所在的父目录添加到我的PYTHONPATH中,因此我可以像处理第三方库一样处理我编写的所有代码


我不认为把PYTHONPATH弄得乱七八糟有什么问题,因为只有带有
\uuu init\uuuu.py
的文件夹才是可导入的

除了修改sys.path,还有其他方法吗?@bullseye:是的,还有其他方法,例如,为
project
创建
setup.py
,并在运行任何脚本之前安装它。安装过程将
code
放入已在
sys.path
中的目录,即在这种情况下,
sys.path
不会被修改。您也可以使用Python 3中的
imp
(或
importlib
)从任何源代码导入任何代码,但您不应该在普通情况下使用它。除了修改sys.path之外,还有其他方法吗?@bullseye:是的,还有其他方法,例如。,为
project
创建
setup.py
,并在运行任何脚本之前安装它。安装过程将
code
放入已在
sys.path
中的目录,即在这种情况下,
sys.path
不会被修改。您也可以使用Python 3中的
imp
(或
importlib
)从任何源代码导入任何代码,但您不应该在普通情况下使用它。那么导入是绝对的吗,我指的是project.code.module?它不是相对正确的,但仍然是一个更干净的解决方案,我在我的环境变量中添加了一个PYTHONPATH变量。我的代码没有将当前目录添加到路径。它搜索包含假定问题(“相对导入”)2所暗示的共同祖先的
code
Python包的父目录。添加当前目录是毫无意义的,因为当
script.py
作为脚本运行时,它已经在
sys.path
中。修改
sys.path
肯定是一个肮脏的攻击。1.
.pth
文件可能更糟糕,除非它是在安装包时由
setup.py
创建的。如果您正在创建文件;为什么不创建一个简单的
setup.py
文件并正确安装模块?为什么需要
project
目录作为Python包?如果可以访问
code
包就足够了(我假设它不是真名,否则它会用相同的名称隐藏stdlib模块),在这种情况下
code
包的行为与任何其他包一样。2.PYTHONPATH甚至比
.pth
文件更具全局性(更大的潜在损害)那么导入是否是绝对的,我是说project.code.module?它不是相对正确的,但仍然是一个更干净的解决方案,我在我的环境变量中添加了一个PYTHONPATH变量。我的代码没有将当前目录添加到路径。信息技术
# insert `code/__init__.py` parent directory into `sys.path`
import sys, os

path = os.path.abspath(sys.argv[0]) # path to bin/script.py
while os.path.dirname(path) != path: # until top-most directory
    if os.path.exists(os.path.join(path, 'code', '__init__.py')):
        sys.path.insert(0, path)
        break
    path = os.path.dirname(path)