我如何 运行 一个 Python 3 脚本从子文件夹导入?
How can I run a Python 3 script with imports from a subfolder?
无论我尝试什么,自从我切换到 Python 3 我可以 运行 脚本只从项目的根文件夹导入,但不能从子文件夹。我知道这里有很多关于我收到的错误消息的问题,但建议的解决方案对我不起作用。有人可以为这个小示例项目提供示例解决方案吗?相信很多人都会喜欢的。
proj
├── foofolder
│ ├── __init__.py
│ └── foofile.py
├── subfolder
│ ├── __init__.py
│ └── run.py
└── __init__.py
我在foofile.py
中定义了函数foofun()
,想在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']
我在虚拟环境中使用 Python 3.5.2。
编辑:我说这个问题是特定于Python时我错了 3.问题和解决方案在我检查时是一样的Python 2.7.12.
Pevogam 给出的解决方案有效。第一个从字面上只是将 '..'
添加到 'sys.path'
,它描述了执行 run.py
的父文件夹。第二个明确添加 '/parent/proj'
.
我能想到的最快的方法是:
# 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 可能会执行他们自己的项目扫描,这就是只要您 运行 python 中的 python 代码,他们仍可能找到导入的原因=26=].
我通常在 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?
问:如何运行 python 子文件夹中的脚本?
A:调用使用PYTHONPATH=. python3 subfolder/run.py
添加到 bashrc:alias pys = PYTHONPATH=. python3
。然后 pys subfolder/run.py
有效!
评论:对我来说,脚本就是执行任务的东西。它永远不会被其他东西调用或导入。我有很多。
其中一些是相似的(例如 taskA_reset.py
、taskB_reset.py
)。我更喜欢将其组织为 taskA/reset.py
等。但是,那就不可能再运行他们了!但是,在路径前面加上一个简单的解决方案,它不需要我更改任何 python-代码。
无论我尝试什么,自从我切换到 Python 3 我可以 运行 脚本只从项目的根文件夹导入,但不能从子文件夹。我知道这里有很多关于我收到的错误消息的问题,但建议的解决方案对我不起作用。有人可以为这个小示例项目提供示例解决方案吗?相信很多人都会喜欢的。
proj
├── foofolder
│ ├── __init__.py
│ └── foofile.py
├── subfolder
│ ├── __init__.py
│ └── run.py
└── __init__.py
我在foofile.py
中定义了函数foofun()
,想在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']
我在虚拟环境中使用 Python 3.5.2。
编辑:我说这个问题是特定于Python时我错了 3.问题和解决方案在我检查时是一样的Python 2.7.12.
Pevogam 给出的解决方案有效。第一个从字面上只是将 '..'
添加到 'sys.path'
,它描述了执行 run.py
的父文件夹。第二个明确添加 '/parent/proj'
.
我能想到的最快的方法是:
# 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 可能会执行他们自己的项目扫描,这就是只要您 运行 python 中的 python 代码,他们仍可能找到导入的原因=26=].
我通常在 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?
问:如何运行 python 子文件夹中的脚本?
A:调用使用PYTHONPATH=. python3 subfolder/run.py
添加到 bashrc:alias pys = PYTHONPATH=. python3
。然后 pys subfolder/run.py
有效!
评论:对我来说,脚本就是执行任务的东西。它永远不会被其他东西调用或导入。我有很多。
其中一些是相似的(例如 taskA_reset.py
、taskB_reset.py
)。我更喜欢将其组织为 taskA/reset.py
等。但是,那就不可能再运行他们了!但是,在路径前面加上一个简单的解决方案,它不需要我更改任何 python-代码。