我知道我觉得自己像个白痴。但是看来我的虚拟环境可能有问题,或者我缺少一些非常基本的东西。
我正在创建一个新的python项目,无法导入该项目中的任何包。
我使用了以下命令:
(env) :~/Development]$ mkdir test_proj/
(env) :~/Development]$ cd test_proj/
(env) :~/Development/test_proj]$ mkdir test_package
(env) :~/Development/test_proj]$ cd test_package
(env) :~/Development/test_proj/test_package]$ touch __ini__.py
(env) :~/Development/test_proj/test_package]$ vi test.py
(env) :~/Development/test_proj/test_package]$ cat test.py
test = "test"
(env) :~/Development/test_proj/test_package]$ cd ../
(env) :~/Development/test_proj]$ mkdir test_package2
(env) :~/Development/test_proj]$ cd test_package2
(env) :~/Development/test_proj/test_package2]$ touch __ini__.py
(env) :~/Development/test_proj/test_package2]$ vi test2.py
(env) :~/Development/test_proj/test_package2]$ cat test2.py
from test_package.test import test
print test
(env) :~/Development/test_proj/test_package2]$ python test2.py
Traceback (most recent call last):
File "test2.py", line 1, in <module>
from test_package.test import test
ImportError: No module named test_package.test
这给了我下面的项目结构。我认为我没有错过任何事情。
test_proj
|
|__test_package
| |__ __init__.py
| |__ test.py
|
|__test_package2
|__ __init__.py
|__ test2.py
我确实在同一虚拟环境中还有其他项目,并且它们运行正常。
我也尝试将此路径附加到PYTHONPATH sys.path。这项工作也没有,我不认为我应该完全添加这条路。
我也尝试使用pycharm做同样的事情,并且遇到同样的错误。 我想念什么吗?
如果我使用相对导入,那么我得到
ValueError: Attempted relative import in non-package
我将不胜感激。抱歉,我知道这一定是愚蠢的,只是我花了很多时间而没有成功。
更新:我正在使用Python 2.7
答案 0 :(得分:2)
您的问题是,您试图从程序包的中间运行代码,同时仍然尝试将其用作程序包的一部分。你不能那样做。
在Python中,当您启动解释器时,您正在运行的脚本的路径或当前工作目录将添加到sys.path
。
这意味着~/Development/test_proj/test_package2/
在您的路径上,但~/Development/test_proj/
不在您的路径上。当然,test_package
中没有名为~/Development/test_proj/test_package2/
的东西,因此没有名为test_package
的程序包,也没有名为test_package.test
的模块。
如果您确实需要从包中运行文件,请将其作为模块而不是脚本运行:
(env) :~/Development/test_proj/]$ python -m test_package2.test2
现在,~/Development/test_proj/
在您的路径上,并且包含目录test_package
,因此您有一个名为test_package
的软件包和一个名为test_package.test
的软件包。
如果您想要一个可作为脚本运行的脚本,请在顶层编写一个包装器脚本,它将from test_package2 import test2
,然后在其上调用诸如test_package2.main()
之类的函数。
然后您只需运行该包装脚本:
(env) :~/Development/test_proj/]$ python test2wrapper.py
同样,由于它位于test_proj
中,而不是test_proj/test_package2
中,因此您的路径正是您想要的。
如果您要在setuptools
周围构建软件包,以便可以用pip
等分发,则可能需要在setup.py
中指定入口点,并让其生成入口点脚本,而不是手动执行。这样,它可以在安装时执行相同的操作,并确保脚本最终放置在可访问的位置,而不是可能放在.zip
或.egg
存档的中间,并且脚本具有正确的位置。为其安装的系统换行,等等。
我也尝试将此路径附加到PYTHONPATH sys.path。
如果将~/Development/test_proj/
添加到PYTHONPATH
,或手动将其添加到sys.path
,它将起作用。我的猜测是您添加了错误的内容,或者忘记对它们进行波浪式扩展,但是却没有看到自己尝试过的内容,这只是一个猜测;我可以肯定地说的是您做错了什么。
但是无论如何,这不是您想要的解决方案。因为现在同一文件test2.py
(除了是顶层脚本__main__
之外)是顶层模块test2
和打包模块test_package2.test2
的全部。>
将软件包目录及其父目录放在sys.path
上是非法的。实际上,没有Python实现会对此进行实际测试,但是它会引起整个世界的混乱,毫无益处,因此您仍然不想这样做。
如果我使用相对导入,那么我会得到
ValueError: Attempted relative import in non-package
是的,因为您运行事物的方式,test2.py
是顶级脚本__main__
,而不是打包的模块test_package2.test2
。它不在包装中,因此..
是非法的。
但是,经过上述任一修复后,相对路径将起作用。