python项目不读取其模块

时间:2018-07-23 04:52:35

标签: python

我知道我觉得自己像个白痴。但是看来我的虚拟环境可能有问题,或者我缺少一些非常基本的东西。

我正在创建一个新的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

1 个答案:

答案 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。它不在包装中,因此..是非法的。

但是,经过上述任一修复后,相对路径将起作用。