无论我尝试什么,,因为我切换到Python 3 我只能从项目的根文件夹运行脚本,但不能从子文件夹运行。我知道这里有很多关于我得到的错误信息的问题,但建议的解决方案对我不起作用。有人可以为这个小样本项目提供样本解决方案吗?我相信很多人都会赞赏。
proj
├── foofolder
│ ├── __init__.py
│ └── foofile.py
├── subfolder
│ ├── __init__.py
│ └── run.py
└── __init__.py
我在foofun()
中定义了foofile.py
函数,并希望在run.py
中调用它。
如果run.py
直接位于proj
,则可行。但是(只是为了让事情井然有序)我希望将它放在一个子文件夹中 - 这显然是不可能的。
令人讨厌的是,我的IDE(PyCharm)中的自动完成功能表明from foofolder.foofile import foofun
应该有效。但事实并非如此。我无法想象任何其他进口:
from foofolder.foofile import foofun
- > ImportError: No module named 'foofolder'
from .foofolder.foofile import foofun
- > SystemError: Parent module '' not loaded, cannot perform relative import
(开头有两个点。)
from proj.foofolder.foofile import foofun
- > ImportError: No module named 'proj'
甚至绝对导入都不起作用。为什么找不到proj
?
sys.path
是:['/parent/proj/subfolder', '/parent/env/lib/python35.zip', '/parent/env/lib/python3.5', '/parent/env/lib/python3.5/plat-x86_64-linux-gnu', '/parent/env/lib/python3.5/lib-dynload', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-x86_64-linux-gnu', '/parent/env/lib/python3.5/site-packages']
我在virtualenv中使用Python 3.5.2。
编辑:当我提出此问题是针对Python 3时,我错了。当我在Python 2.7.12中检查时问题和解决方案是相同的。
Pevogam提供的解决方案。第一个字面上只添加'..'
到'sys.path'
,它描述了执行run.py
的父文件夹。第二个明确添加了'/parent/proj'
。
答案 0 :(得分:1)
我能从头脑中思考这个问题的最快方式是:
# subfolder/run.py
import sys
sys.path.append("..")
from foofolder.foofile import foofun
foofun()
但请注意,只有从其文件夹中运行 run.py 时,此方法才有效。一种不依赖于此的更复杂的方法是
# subfolder/run.py
import sys
import os.path as o
sys.path.append(o.abspath(o.join(o.dirname(sys.modules[__name__].__file__), "..")))
from foofolder.foofile import foofun
foofun()
您可以从任何位置到达该功能。对所有这些模块最简单的做法是使用相同的指针指向根包,在你的情况下通过添加" .."。然后,您可以从此根包的角度执行任何导入。
我倾向于避免使用相对导入,因为它们令人困惑并降低了可读性,但希望其中一些有用。
[*]有些IDE可能会执行自己的项目扫描,这是他们在IDE中运行python代码时仍然可以找到导入的原因。
答案 1 :(得分:0)
我通常在Django项目中需要此功能,只是意识到Django提供了一个非常方便的解决方案,可以为我解决此问题:
$ python manage.py shell < app/utils/scripts/script.py
在script.py
中,我的导入内容如下:
from app.utils.functions.do_things import do_this, do_that