如何使用子文件夹中的导入运行Python 3脚本?

时间:2018-03-04 13:22:19

标签: python-import sys

无论我尝试什么,,因为我切换到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'

2 个答案:

答案 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

在这里找到:How to execute a Python script from the Django shell?