在目录之间导入模块
Importing Module Between Directories
更新(显示最终代码)
因为这似乎很难解释,所以我分享了这个项目。对于那些提出这个问题的人,你可以在这里看到完整的项目:
https://github.com/jeffnyman/pacumen
调出对我来说有问题的文件:
graphical_pacman
https://github.com/jeffnyman/pacumen/blob/master/displays/graphical_pacman.py
布局
https://github.com/jeffnyman/pacumen/blob/master/mechanics/layout.py
有了 __init__.py
和 setup.py
文件,我现在可以 运行 这样的命令:
python displays/graphical_pacman.py
python mechanics/layout.py
执行这些命令时,所有导入现在都能正确解析。您可以看到我在每个文件中使用的所有导入语句以及各种 __init__.py
文件的位置。
原始问题
我无法完成看似简单的工作:在目录之间导入模块。这些都在 Python 3 中,所以如果可以的话,我不想到处都是 __init__.py
文件,这里的许多答案都建议使用 "right" 方式。
我有这样的结构:
project
displays
graphical_pacman.py
mechanics
layout.py
layout.py 文件有一个名为 get_layout() 的顶级函数,我想从 graphical_pacman.py.
调用它
转到所需的最少代码,在 graphical_pacman.py 我有:
import layout
if __name__ == '__main__':
board = layout.get_layout("test_maze.lay")
在 IDE 中显示良好,甚至自动完成它。 运行 graphical_pacman.py 让我得到这个:
File "displays/graphical_pacman.py", line 3, in <module>
import layout
ModuleNotFoundError: No module named 'layout'
然后我试了这个:
from mechanics.layout import get_layout
if __name__ == '__main__':
board = mechanics.layout.get_layout("test_maze.lay")
也做不到:
File "displays/graphical_pacman.py", line 3, in <module>
from mechanics.layout import get_layout
ModuleNotFoundError: No module named 'mechanics'
我试过这个:
from mechanics import layout
if __name__ == '__main__':
board = layout.get_layout("test_maze.lay")
我试过这个:
from layout import get_layout
if __name__ == '__main__':
board = get_layout("test_maze.lay")
无效。明白了:
File "displays/graphical_pacman.py", line 3, in <module>
from layout import get_layout
ModuleNotFoundError: No module named 'layout'
我尝试使用相对导入(在事物前面加上 .),但这也不起作用。我也刚刚尝试使用 * 进行导入(本质上是导入所有内容)。也不起作用。当我说 "doesn't work" 时,我得到了上述错误的一些变体。
我已经从 displays
目录和根 project
目录中尝试了所有这些 运行ning 命令 python graphical_pacman.py
。每次都出现同样的错误。
我也试过使用 sys.path,比如这个 sys.path.insert(0, '../mechanics')
。我还根据我在这里看到的其他答案尝试了 sys.path.append('../')
的变体。同样,我得到的只是上述错误的变体。
我错过了什么?
第二次更新:
我已经发送了拉取请求,请查看。
这是我所做的:我从项目根目录创建了一个包,并使用 pip 安装了它。详情如下:
添加的文件:
pacumen
__init__.py
setup.py
displays
__init__.py
library
__init__.py
mechanics
__init__.py
pacumen/__init__.py 的内容:
from . import displays
from . import library
from . import mechanics
pacumen/setup.py 的内容:
import setuptools
setuptools.setup(
name='pacumen',
version='0.01dev',
packages=['displays',
'library',
'mechanics',
],
author='jefferyman',
author_email='something@something.com',
description='Pacman. Duh.',
long_description=open('README.md').read(),
)
pacumen/displays/__init__.py 的内容:
from . import graphical_helpers
from . import graphical_pacman
from . import graphical_support
pacumen/library/__init__.py 的内容:
from . import structures
from . import utilities
pacumen/mechanics/__init__.py 的内容:
from . import grid
from . import layout
文件变化:
pacumen/mechanics/layout.py:
from mechanics.grid import Grid
确保您的虚拟环境处于活动状态。 (进一步说明)。
最后,导航到项目根目录并将项目根目录安装为包:
pip install --editable . # or pip install -e . (Note the period at the end)
现在只要激活了虚拟环境,导入应该就没有问题了。请确保使用样式的导入语句:
from mechanics.grid import Grid
虚拟环境创建和激活:
对于阅读者来说,现在是创建虚拟环境的好时机(如果尚未创建的话)。如果确保激活它。如果没有,导航到项目目录的根目录 (pacumen) 和 运行
$ python -m venv venvdir
然后,一旦创建,运行:
<project-root>$ .venvdir\Scripts\activate # for windows.
OR
<project-root>$ source venvdir/bin/activate # for linux bash
更新:首先要检查的是没有循环导入,这意味着您正在从 graphical_pacman 中导入一些来自 mechanics 的东西,以及一些来自 graphical_pacman 的 mechanics 中的其他东西。还要确保您的模块名称不与内置 python 模块的名称冲突。如果在这些方面都很好,
- 你试过吗?
from project.mechanics import layout
- 如果这不起作用,请将 __init__.py 文件放入项目、显示、机制中。
在 project/displays/__init__.py 添加 from . import graphical_pacman
.
在 project/mechanics/__init__.py 添加 from. import layout
.
- 如果这些都不起作用,请从中创建一个包,导航到包根目录并使用
pip install -e .
在您的环境中安装它
我有一些有用的东西,所以我有 的答案,但完整的答案是我正在做的事情在 Python 中无法完成,到目前为止据我所知。这里的部分问题是,随着我了解更多,我意识到我的问题在我希望事情如何执行方面措辞不够好。
下面是可以工作的方式。如果在 graphical_pacman.py
,我这样做:
if __name__ == '__main__':
sys.path.append('../')
from mechanics import layout
board = layout.get_layout("test_maze.lay")
终于成功了!
但是...
我必须从 displays
目录而不是项目根目录中 运行 python graphical_pacman.py
。 (意思是,我无法从项目根目录执行此命令:python displays\graphical_pacman.py
。)
但是...
执行仍然 运行s 出错:
Traceback (most recent call last):
File "graphical_pacman.py", line 18, in <module>
from mechanics import layout
File "../mechanics/layout.py", line 4, in <module>
from grid import Grid
ModuleNotFoundError: No module named 'grid'
这是来自 layout.py
中的这一行:
from grid import Grid
如果我将该行更改为相对导入:
from .grid import Grid
现在 当 displays
目录中的 运行 时,我的 python graphical_pacman.py
命令有效。
但是...
现在我不能只 运行 python layout.py
,这也需要成为可能。这显然是因为相对导入现在在那里,所以我得到这个错误:
Traceback (most recent call last):
File "layout.py", line 4, in <module>
from .grid import Grid
ModuleNotFoundError: No module named '__main__.grid'; '__main__' is not a package
我发现的问题是我有时需要单独 运行 文件。您会看到 mechanics\layout.py
有一个 if __name__ == '__main__':
部分。 displays\graphical_support.py
也是如此。这些是必要的,这样人们就可以通过 运行 直接查看这些文件来了解工作原理。但最终这些将由目录根目录中的文件 used/imported 编排所有内容。有时文件(如布局)将依赖于其他文件(如网格)。
所以看起来答案是Python做不到我想做的,这基本上只是寻求灵活性。
我想我可以通过将所有文件放在一个目录中来处理所有这些问题,这似乎是这里的最佳答案,而且其他项目似乎也是这样做的。这似乎是一个糟糕的方法,但我正在权衡与导入机制的斗争,特别是因为我现在发现该机制根据执行以不同的方式工作。
更新(显示最终代码)
因为这似乎很难解释,所以我分享了这个项目。对于那些提出这个问题的人,你可以在这里看到完整的项目:
https://github.com/jeffnyman/pacumen
调出对我来说有问题的文件:
graphical_pacman
https://github.com/jeffnyman/pacumen/blob/master/displays/graphical_pacman.py
布局
https://github.com/jeffnyman/pacumen/blob/master/mechanics/layout.py
有了 __init__.py
和 setup.py
文件,我现在可以 运行 这样的命令:
python displays/graphical_pacman.py
python mechanics/layout.py
执行这些命令时,所有导入现在都能正确解析。您可以看到我在每个文件中使用的所有导入语句以及各种 __init__.py
文件的位置。
原始问题
我无法完成看似简单的工作:在目录之间导入模块。这些都在 Python 3 中,所以如果可以的话,我不想到处都是 __init__.py
文件,这里的许多答案都建议使用 "right" 方式。
我有这样的结构:
project
displays
graphical_pacman.py
mechanics
layout.py
layout.py 文件有一个名为 get_layout() 的顶级函数,我想从 graphical_pacman.py.
调用它转到所需的最少代码,在 graphical_pacman.py 我有:
import layout
if __name__ == '__main__':
board = layout.get_layout("test_maze.lay")
在 IDE 中显示良好,甚至自动完成它。 运行 graphical_pacman.py 让我得到这个:
File "displays/graphical_pacman.py", line 3, in <module>
import layout
ModuleNotFoundError: No module named 'layout'
然后我试了这个:
from mechanics.layout import get_layout
if __name__ == '__main__':
board = mechanics.layout.get_layout("test_maze.lay")
也做不到:
File "displays/graphical_pacman.py", line 3, in <module>
from mechanics.layout import get_layout
ModuleNotFoundError: No module named 'mechanics'
我试过这个:
from mechanics import layout
if __name__ == '__main__':
board = layout.get_layout("test_maze.lay")
我试过这个:
from layout import get_layout
if __name__ == '__main__':
board = get_layout("test_maze.lay")
无效。明白了:
File "displays/graphical_pacman.py", line 3, in <module>
from layout import get_layout
ModuleNotFoundError: No module named 'layout'
我尝试使用相对导入(在事物前面加上 .),但这也不起作用。我也刚刚尝试使用 * 进行导入(本质上是导入所有内容)。也不起作用。当我说 "doesn't work" 时,我得到了上述错误的一些变体。
我已经从 displays
目录和根 project
目录中尝试了所有这些 运行ning 命令 python graphical_pacman.py
。每次都出现同样的错误。
我也试过使用 sys.path,比如这个 sys.path.insert(0, '../mechanics')
。我还根据我在这里看到的其他答案尝试了 sys.path.append('../')
的变体。同样,我得到的只是上述错误的变体。
我错过了什么?
第二次更新:
我已经发送了拉取请求,请查看。
这是我所做的:我从项目根目录创建了一个包,并使用 pip 安装了它。详情如下:
添加的文件:
pacumen
__init__.py
setup.py
displays
__init__.py
library
__init__.py
mechanics
__init__.py
pacumen/__init__.py 的内容:
from . import displays
from . import library
from . import mechanics
pacumen/setup.py 的内容:
import setuptools
setuptools.setup(
name='pacumen',
version='0.01dev',
packages=['displays',
'library',
'mechanics',
],
author='jefferyman',
author_email='something@something.com',
description='Pacman. Duh.',
long_description=open('README.md').read(),
)
pacumen/displays/__init__.py 的内容:
from . import graphical_helpers
from . import graphical_pacman
from . import graphical_support
pacumen/library/__init__.py 的内容:
from . import structures
from . import utilities
pacumen/mechanics/__init__.py 的内容:
from . import grid
from . import layout
文件变化:
pacumen/mechanics/layout.py:
from mechanics.grid import Grid
确保您的虚拟环境处于活动状态。 (进一步说明)。
最后,导航到项目根目录并将项目根目录安装为包:
pip install --editable . # or pip install -e . (Note the period at the end)
现在只要激活了虚拟环境,导入应该就没有问题了。请确保使用样式的导入语句:
from mechanics.grid import Grid
虚拟环境创建和激活:
对于阅读者来说,现在是创建虚拟环境的好时机(如果尚未创建的话)。如果确保激活它。如果没有,导航到项目目录的根目录 (pacumen) 和 运行
$ python -m venv venvdir
然后,一旦创建,运行:
<project-root>$ .venvdir\Scripts\activate # for windows.
OR
<project-root>$ source venvdir/bin/activate # for linux bash
更新:首先要检查的是没有循环导入,这意味着您正在从 graphical_pacman 中导入一些来自 mechanics 的东西,以及一些来自 graphical_pacman 的 mechanics 中的其他东西。还要确保您的模块名称不与内置 python 模块的名称冲突。如果在这些方面都很好,
- 你试过吗?
from project.mechanics import layout
- 如果这不起作用,请将 __init__.py 文件放入项目、显示、机制中。
在 project/displays/__init__.py 添加from . import graphical_pacman
.
在 project/mechanics/__init__.py 添加from. import layout
. - 如果这些都不起作用,请从中创建一个包,导航到包根目录并使用
pip install -e .
在您的环境中安装它
我有一些有用的东西,所以我有 的答案,但完整的答案是我正在做的事情在 Python 中无法完成,到目前为止据我所知。这里的部分问题是,随着我了解更多,我意识到我的问题在我希望事情如何执行方面措辞不够好。
下面是可以工作的方式。如果在 graphical_pacman.py
,我这样做:
if __name__ == '__main__':
sys.path.append('../')
from mechanics import layout
board = layout.get_layout("test_maze.lay")
终于成功了!
但是...
我必须从 displays
目录而不是项目根目录中 运行 python graphical_pacman.py
。 (意思是,我无法从项目根目录执行此命令:python displays\graphical_pacman.py
。)
但是...
执行仍然 运行s 出错:
Traceback (most recent call last):
File "graphical_pacman.py", line 18, in <module>
from mechanics import layout
File "../mechanics/layout.py", line 4, in <module>
from grid import Grid
ModuleNotFoundError: No module named 'grid'
这是来自 layout.py
中的这一行:
from grid import Grid
如果我将该行更改为相对导入:
from .grid import Grid
现在 当 displays
目录中的 运行 时,我的 python graphical_pacman.py
命令有效。
但是...
现在我不能只 运行 python layout.py
,这也需要成为可能。这显然是因为相对导入现在在那里,所以我得到这个错误:
Traceback (most recent call last):
File "layout.py", line 4, in <module>
from .grid import Grid
ModuleNotFoundError: No module named '__main__.grid'; '__main__' is not a package
我发现的问题是我有时需要单独 运行 文件。您会看到 mechanics\layout.py
有一个 if __name__ == '__main__':
部分。 displays\graphical_support.py
也是如此。这些是必要的,这样人们就可以通过 运行 直接查看这些文件来了解工作原理。但最终这些将由目录根目录中的文件 used/imported 编排所有内容。有时文件(如布局)将依赖于其他文件(如网格)。
所以看起来答案是Python做不到我想做的,这基本上只是寻求灵活性。
我想我可以通过将所有文件放在一个目录中来处理所有这些问题,这似乎是这里的最佳答案,而且其他项目似乎也是这样做的。这似乎是一个糟糕的方法,但我正在权衡与导入机制的斗争,特别是因为我现在发现该机制根据执行以不同的方式工作。