我是Python的新手,我在这个简单的例子中遇到了以下错误。
这是我的项目结构
python_project
.
├── lib
│ ├── __init__.py
│ └── my_custom_lib.py
└── src
├── __init__.py
└── main.py
这是当我执行 src/main.py
文件。
☁ python_project python src/main.py
Traceback (most recent call last):
File "src/main.py", line 3, in <module>
from lib import my_custom_lib
ImportError: No module named lib
如果我移动 main.py
文件到根目录,然后我再执行这个文件,工作......但在内部不能工作 src/
目录
这是我的 main.py
:
from lib import my_custom_lib
def do_something(message):
my_custom_lib.show(message)
do_something('Hello World!')
注意: 当我执行同样的代码时,从 Pycharm 可以正常工作,但在我的终端上就不行了。
你的 PYTHONPATH 被设置为你执行的程序的当前目录。所以,如果你在一个目录下执行的是 src
,它将永远无法找到目录 lib
因为它在路径之外。有几个选择。
lib/
变成 src/
如果它属于你的代码。如果是外部包,应该像Henrique Branco提到的那样安装pip。src/
导入并运行 src.main
. 这将把顶级目录添加到python路径中。src/main.py
修改 sys.path
来包含顶层目录。这通常是不受欢迎的。src/main.py
作为一个模块,具有 python -m src.main
这将把顶层目录添加到python路径中。打字有点麻烦,而且你需要修改所有的导入。你使用的是 from a import b
错了,它应该是这样的。
import lib.my_custom_lib
另一个方法是用来从模块中导入某些方法,函数和类,而不是模块本身。要从my_custom_lib模块中导入一个特定的函数,它应该是这样的。
from lib.my_custom_lib import foo
如果我可以补充一下 MarkM的回答如果你想保持你当前的目录结构,并使它仍然工作,你可以添加一个 setup.py
在你的根目录下,你可以使用 设置工具 来创建一个可以安装的软件包。
如果你的文件有一些类似的内容。
# setup.py
from setuptools import find_packages, setup
setup(
name='foo',
version=`1.0.0`,
packages=find_packages(),
entrypoints={
'console_scripts': [
'foo=src.main:main',
],
},
)
然后你就会 pip install [--user] -e path/to/directory
你会得到一个 "可编辑包",它将有效地与你的开发目录中的包建立一个符号链接,所以你所做的任何更改都不需要重新安装(当然,除非你重新调整包结构或添加removeedit入口点)。
这确实假设你的 src/main.py
有一个主要功能。
您还需要 __init__.py
文件在你的 "package "目录中,即使在Python3中也是如此,否则Python会认为这些是命名空间的包(不会去细说),而 find_packages()
调用不会找到它们。
这也将允许你的相对导入工作。绝对导入只有在从你的入口点调用脚本时才会起作用,但在你的开发目录中直接调用脚本时就不行了。
请尝试使用相对导入来代替。
from ..lib import my_custom_lib