我是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 执行相同的代码时,可以正常工作,但不能从我的终端上正常工作。
答案 0 :(得分:4)
您执行的程序将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路径。有点烦人,而且您需要更改所有导入。答案 1 :(得分:1)
您使用的from a import b
错误。它应该看起来像这样:
import lib.my_custom_lib
另一种方法用于从模块而不是模块本身导入某些方法,函数和类。要从my_custom_lib模块导入特定的函数,它将看起来像这样:
from lib.my_custom_lib import foo
答案 2 :(得分:1)
尝试使用相对导入:
from ..lib import my_custom_lib
答案 3 :(得分:1)
如果我可以添加到MarkM's answer,如果您想保留当前目录结构并使它仍然有效,则可以在根目录中添加一个setup.py
,您可以在其中使用{{3 }}来创建您可以安装的软件包。
如果文件中包含以下内容:
# 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
,您将获得一个“可编辑的程序包”,该程序包将有效链接到开发目录中的程序包,因此您所做的任何更改都不需要重新安装(当然,除非您重新设置目录,包结构或添加/删除/编辑入口点。
这确实假设您的src/main.py
具有主要功能。
即使在Python3中,您也需要在“包”目录中需要__init__.py
个文件,否则Python会假定它们是名称空间包(不会详细介绍),并且会赢得find_packages()
调用找不到它们。
这也将允许您的相对进口货物使用。绝对导入仅在从入口点调用脚本时有效,而在直接在开发目录中调用脚本时则无效。
答案 4 :(得分:1)
您的 main.py 脚本应该位于目录结构中的所有 python 包之上。尝试将您的项目更新为以下结构:
.
|__ main.py
|__ lib
| |__ __init__.py
| |__ your_custom_lib.py
|__ another_python_package
|__ __init__.py
|__ another_python_scripts
之后,您项目目录中的 python main.py
将起作用。