首先,关于这一点,有很多关于堆栈溢出的解决方案,但从我尝试过的那些解决方案来看,它们都不起作用。我正在开发一台远程计算机(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_1中导入module_2。但是,在这个堆栈溢出帖子中提到的解决方案:使用链接
sys.path.append('../..')
import module_2不管用。我得到了错误:ModuleNotFoundError: No module named 'module_1'
此外,在ipython解释器中,如import .module_3在module_2中抛出错误:
导入.module_3 ^ SyntaxError:无效语法
点操作符不也应该在同一个目录下工作吗。总的来说,我对进口机制感到很困惑。任何对初始问题的帮助都是非常感谢的!非常感谢!
发布于 2020-09-28 22:24:41
为什么不起作用?
如果您运行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 notmodule2.py文件。
语法import .module_3用于相对导入。如果您尝试执行module2.py,并且它包含import .module_3,它将无法工作,因为您正在使用module2.py作为脚本。要使用相对导入,需要将module2.py和module_3.py视为模块。也就是说,其他一些文件使用这个语法导入module2和module2,从module3导入一些东西。
关于如何进行的建议
解决这两个问题的一个可能的解决方案是属性组织项目,并(可选地,提供一个好主意)打包您的库(也就是说,使代码“可安装”)。然后,一旦安装了库(在您正在工作的虚拟环境中),您就不需要sys.path解决方案了。您可以从任何文件夹导入您的库。
此外,不要将模块视为脚本(不要运行模块)。使用单独的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:您不想打包您的库
如果您不想打包您的库,那么可以在sys.path.append("../")中main.py中添加“project-dir/文件夹到路径”。这样,您的yourlib库在main.py中将是“可导入的”。您可以执行类似from yourlib import module_2的操作,它将正确工作( module_2可以使用相对导入)。或者,您也可以直接将main.py放在project-dir/文件夹中,根本不需要更改sys.path,因为在这种情况下,project-dir/将是“工作目录”。
请注意,您还可以在tests中拥有一个project-dir文件夹,要运行测试文件,您可以执行与运行main.py相同的操作。
案例2:您想要打包您的库
前面的解决方案已经解决了您的问题,但是做更多的工作会带来一些好处,比如依赖关系管理,无论您在哪里都不需要更改sys.path。有几个选项可以打包您的库,由于它的简单性,我将展示一个使用诗歌的选项。
安装完诗歌之后,可以在终端中运行下面的命令来创建一个新项目。
poetry new mylib这将创建以下文件夹结构
mylib/
- README.rst
- mylib/
- __init__.py
- pyproject.toml
- tests然后,如果需要,可以添加apps文件夹,也可以在mylib/中添加子文件夹(每个文件夹都有一个__init__.py文件)。
pyproject.toml文件指定依赖项和项目元数据。您可以手工编辑它和/或使用诗歌添加新的依赖项,例如
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;DR
使用有组织的项目结构,为您执行的脚本提供一个清晰的位置。特别是,如果您执行的脚本与您的模块在文件夹之外,则更好。另外,不要将模块作为脚本运行(否则不能使用相对导入)。
https://stackoverflow.com/questions/64107888
复制相似问题