我运行的是Python 2.5。
这是我的文件夹树:
ptdraft/
nib.py
simulations/
life/
life.py
(我在每个文件夹中都有__init__.py,为了可读性,这里省略了)
我如何从生命模块内导入nib模块?我希望不需要修改sys.path就可以做到。
注意:正在运行的主模块在ptdraft文件夹中。
我运行的是Python 2.5。
这是我的文件夹树:
ptdraft/
nib.py
simulations/
life/
life.py
(我在每个文件夹中都有__init__.py,为了可读性,这里省略了)
我如何从生命模块内导入nib模块?我希望不需要修改sys.path就可以做到。
注意:正在运行的主模块在ptdraft文件夹中。
当前回答
我们的文件夹结构:
/myproject
project_using_ptdraft/
main.py
ptdraft/
__init__.py
nib.py
simulations/
__init__.py
life/
__init__.py
life.py
我理解这一点的方式是以包为中心的观点。 包根是ptdraft,因为它是包含__init__.py的最顶层
例如,包中的所有文件都可以使用绝对路径(相对于包根)进行导入 在life.py中,我们简单地有:
import ptdraft.nib
然而,为了包开发/测试目的而运行life.py,而不是python life.py,我们需要使用:
cd /myproject
python -m ptdraft.simulations.life.life
注意,在这一点上,我们根本不需要修改任何路径。
更令人困惑的是,当我们完成ptdraft包时,我们想在一个驱动程序脚本中使用它,它必须在ptdraft包文件夹之外,也就是project_using_ptdraft/main.py,我们需要摆弄路径:
import sys
sys.path.append("/myproject") # folder that contains ptdraft
import ptdraft
import ptdraft.simulations
使用python main.py运行脚本没有问题。
有用的链接:
https://tenthousandmeters.com/blog/python-behind-the-scenes-11-how-the-python-import-system-works/(查看如何使用__init__.py) https://chrisyeh96.github.io/2017/08/08/definitive-guide-python-imports.html#running-package-initialization-code https://stackoverflow.com/a/50392363/2202107 https://stackoverflow.com/a/27876800/2202107
其他回答
虽然这是违反所有规则的,但我还是想提一下这种可能性:
您可以先将文件从父目录复制到子目录。接下来导入它,然后删除复制的文件:
例如,在life.py中:
import os
import shutil
shutil.copy('../nib.py', '.')
import nib
os.remove('nib.py')
# now you can use it just fine:
nib.foo()
当然,当nibs尝试使用相对导入/路径导入/读取其他文件时,可能会出现一些问题。
你可以在“模块搜索路径”中使用OS依赖路径。路径。 因此,您可以轻松地添加如下父目录
import sys
sys.path.insert(0,'..')
如果要添加父-父目录,
sys.path.insert(0,'../..')
这在python2和python3中都适用。
我有一个问题,我必须导入一个Flask应用程序,它有一个导入,也需要在单独的文件夹中导入文件。这部分使用了Remi的答案,但假设我们有一个像这样的存储库:
.
└── service
└── misc
└── categories.csv
└── test
└── app_test.py
app.py
pipeline.py
然后,在从app.py文件导入app对象之前,我们将目录向上更改一层,因此当我们导入app(它导入了pipeline.py)时,我们也可以读入其他文件,如csv文件。
import os,sys,inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0,parentdir)
os.chdir('../')
from app import app
在导入Flask应用程序之后,你可以使用os.chdir('./test'),这样你的工作目录就不会被改变。
这是对我来说最简单的解决方法:
from ptdraft import nib
二线最简解
import os, sys
sys.path.insert(0, os.getcwd())
如果父目录是你的工作目录,你想从子脚本调用另一个子模块。
您可以在任何脚本中从父目录导入所有子模块并执行
python child_module1/child_script.py