从当前工作目录上方的目录导入模块
Importing module from a directory above current working directory
首先,Whosebug 上有很多关于此的解决方案,但我尝试过的解决方案 none 是有效的。我正在远程机器上工作 (linux)。我正在使用 ipython 解释器在 dir-2/module_2.py
文件中制作原型。此外,我试图避免使用绝对路径,因为这台远程机器中的绝对路径又长又丑,我希望我的代码在下载后在其他机器上 运行。
我的目录结构如下:
/project-dir/
-/dir-1/
-/__ init__.py
-/module_1.py
-/dir-2/
-/__ init__.py
-/module_2.py
-/module_3.py
现在我想从 module_2
导入 module_1
。然而这个Whosebug post中提到的解决方案: of using
sys.path.append('../..')
import module_2
无效。我收到错误:ModuleNotFoundError: No module named 'module_1'
此外,在 ipython 解释器中 module_2
中的 import .module_3
会抛出错误:
import .module_3
^ SyntaxError: invalid syntax
点运算符不应该在同一目录中工作吗?总的来说,我对导入机制感到很困惑。非常感谢对最初问题的任何帮助!非常感谢!
为什么它不起作用?
如果你 运行 module1.py
文件并且你想导入 module2
那么你需要像
sys.path.append("../dir-2")
如果你在其中使用 sys.path.append("../..") then the folder you added to the path is the folder containing
project-dirand there is not
module2.py` 文件。
语法import .module_3
用于相对导入。如果您尝试执行 module2.py
并且它包含 import .module_3
它不起作用,因为您正在使用 module2.py
作为脚本。要使用相对导入,您需要将 module2.py
和 module_3.py
都视为模块。也就是说,一些其他文件导入 module2 和 module2 使用此语法从 module3 导入某些内容。
关于如何继续的建议
解决这两个问题的一个可能解决方案是 属性 组织项目和(可选,这是一个好主意)打包您的库(即,使您的代码“可安装”)。然后,一旦你的库安装好了(在你工作的虚拟环境中),你就不需要 hacky sys.path
solutions。您将能够从任何文件夹导入您的库。
此外,不要将您的模块视为脚本(不要 运行 您的模块)。使用单独的 python 文件作为您的“可执行文件”(或入口点)并从那里导入您需要的所有内容。这样,您的 module*.py
文件中的相对导入将正常工作,您不会感到困惑。
一个可能的目录结构可能是
/project-dir/
- apps/
- main.py
- yourlib/
-/__ init__.py
-/dir-1/
-/__ init__.py
-/module_1.py
-/dir-2/
-/__ init__.py
-/module_2.py
-/module_3.py
请注意 yourlib
文件夹及其子文件夹包含一个 __init__.py
文件。使用此结构,您只需 运行 main.py
(名称不需要 main.py
)。
情况 1:您不想打包您的库
如果您不想打包您的库,那么您可以在 main.py
中添加 sys.path.append("../")
以将“project-dir/
文件夹添加到路径中。这样您的 yourlib
库将在 main.py
中“导入”。您可以执行类似 from yourlib import module_2
的操作,它会正常工作(并且 module_2
可以使用相对导入)。或者,您也可以直接将 main.py
放入 project-dir/
文件夹中,您根本不需要更改 sys.path
,因为在这种情况下 project-dir/
将成为“工作目录”。
请注意,您还可以在 project-dir
中有一个 tests
文件夹,并且 运行 一个测试文件,您可以像 运行 main.py
.
情况 2:您想打包您的图书馆
之前的解决方案已经解决了您的问题,但更进一步会带来一些好处,例如依赖管理,并且无论您身在何处都无需更改 sys.path
。有几个选项可以打包你的库,我将使用 poetry 显示一个选项,因为它很简单。
安装poetry后,可以运行在终端中输入下面的命令新建一个项目
poetry new mylib
这将创建以下文件夹结构
mylib/
- README.rst
- mylib/
- __init__.py
- pyproject.toml
- tests
然后您可以根据需要添加 apps
文件夹,以及 mylib/
中的子文件夹(每个子文件夹都有一个 __init__.py
文件)。
pyproject.toml
文件指定依赖项和项目元数据。可以手动编辑and/or使用诗歌添加新的依赖,比如
poetry add pandas
poetry add --dev mypy
例如, 添加 pandas
作为依赖项和 mypy
作为开发依赖项。之后,您可以运行
poetry build
创建虚拟环境并在其中安装您的库。您可以使用 poetry shell
激活虚拟环境,您将能够从任何地方导入您的库。请注意,您可以更改库文件而无需再次 运行 poetry build
。
最后,如果你想在 PyPi 中发布你的库供大家查看,你可以使用
poetry publish --username your_pypi_username --password _passowrd_
TL;博士
使用有条理的项目结构,并为您执行的脚本提供清晰的位置。特别是,如果您执行的脚本位于包含您的模块的文件夹之外会更好。另外,不要 运行 将模块作为脚本(否则你不能使用相对导入)。
首先,Whosebug 上有很多关于此的解决方案,但我尝试过的解决方案 none 是有效的。我正在远程机器上工作 (linux)。我正在使用 ipython 解释器在 dir-2/module_2.py
文件中制作原型。此外,我试图避免使用绝对路径,因为这台远程机器中的绝对路径又长又丑,我希望我的代码在下载后在其他机器上 运行。
我的目录结构如下:
/project-dir/
-/dir-1/
-/__ init__.py
-/module_1.py
-/dir-2/
-/__ init__.py
-/module_2.py
-/module_3.py
现在我想从 module_2
导入 module_1
。然而这个Whosebug post中提到的解决方案:
sys.path.append('../..')
import module_2
无效。我收到错误:ModuleNotFoundError: No module named 'module_1'
此外,在 ipython 解释器中 module_2
中的 import .module_3
会抛出错误:
import .module_3 ^ SyntaxError: invalid syntax
点运算符不应该在同一目录中工作吗?总的来说,我对导入机制感到很困惑。非常感谢对最初问题的任何帮助!非常感谢!
为什么它不起作用?
如果你 运行 module1.py
文件并且你想导入 module2
那么你需要像
sys.path.append("../dir-2")
如果你在其中使用 sys.path.append("../..") then the folder you added to the path is the folder containing
project-dirand there is not
module2.py` 文件。
语法import .module_3
用于相对导入。如果您尝试执行 module2.py
并且它包含 import .module_3
它不起作用,因为您正在使用 module2.py
作为脚本。要使用相对导入,您需要将 module2.py
和 module_3.py
都视为模块。也就是说,一些其他文件导入 module2 和 module2 使用此语法从 module3 导入某些内容。
关于如何继续的建议
解决这两个问题的一个可能解决方案是 属性 组织项目和(可选,这是一个好主意)打包您的库(即,使您的代码“可安装”)。然后,一旦你的库安装好了(在你工作的虚拟环境中),你就不需要 hacky sys.path
solutions。您将能够从任何文件夹导入您的库。
此外,不要将您的模块视为脚本(不要 运行 您的模块)。使用单独的 python 文件作为您的“可执行文件”(或入口点)并从那里导入您需要的所有内容。这样,您的 module*.py
文件中的相对导入将正常工作,您不会感到困惑。
一个可能的目录结构可能是
/project-dir/
- apps/
- main.py
- yourlib/
-/__ init__.py
-/dir-1/
-/__ init__.py
-/module_1.py
-/dir-2/
-/__ init__.py
-/module_2.py
-/module_3.py
请注意 yourlib
文件夹及其子文件夹包含一个 __init__.py
文件。使用此结构,您只需 运行 main.py
(名称不需要 main.py
)。
情况 1:您不想打包您的库
如果您不想打包您的库,那么您可以在 main.py
中添加 sys.path.append("../")
以将“project-dir/
文件夹添加到路径中。这样您的 yourlib
库将在 main.py
中“导入”。您可以执行类似 from yourlib import module_2
的操作,它会正常工作(并且 module_2
可以使用相对导入)。或者,您也可以直接将 main.py
放入 project-dir/
文件夹中,您根本不需要更改 sys.path
,因为在这种情况下 project-dir/
将成为“工作目录”。
请注意,您还可以在 project-dir
中有一个 tests
文件夹,并且 运行 一个测试文件,您可以像 运行 main.py
.
情况 2:您想打包您的图书馆
之前的解决方案已经解决了您的问题,但更进一步会带来一些好处,例如依赖管理,并且无论您身在何处都无需更改 sys.path
。有几个选项可以打包你的库,我将使用 poetry 显示一个选项,因为它很简单。
安装poetry后,可以运行在终端中输入下面的命令新建一个项目
poetry new mylib
这将创建以下文件夹结构
mylib/
- README.rst
- mylib/
- __init__.py
- pyproject.toml
- tests
然后您可以根据需要添加 apps
文件夹,以及 mylib/
中的子文件夹(每个子文件夹都有一个 __init__.py
文件)。
pyproject.toml
文件指定依赖项和项目元数据。可以手动编辑and/or使用诗歌添加新的依赖,比如
poetry add pandas
poetry add --dev mypy
例如, 添加 pandas
作为依赖项和 mypy
作为开发依赖项。之后,您可以运行
poetry build
创建虚拟环境并在其中安装您的库。您可以使用 poetry shell
激活虚拟环境,您将能够从任何地方导入您的库。请注意,您可以更改库文件而无需再次 运行 poetry build
。
最后,如果你想在 PyPi 中发布你的库供大家查看,你可以使用
poetry publish --username your_pypi_username --password _passowrd_
TL;博士
使用有条理的项目结构,并为您执行的脚本提供清晰的位置。特别是,如果您执行的脚本位于包含您的模块的文件夹之外会更好。另外,不要 运行 将模块作为脚本(否则你不能使用相对导入)。