从不同层次的层次导入Python模块 [英] Importing Python modules from different levels of hierarchy
问题描述
在git存储库的顶层,我具有以下文件结构:
Within the top level of my git repository, I have the following file structure:
miscellaneous Dockerfiles, readme, etc
Code/
training.py
data/
generate.py
tasksets.py
有时候,当我将 tasksets
模块作为脚本运行时,我想从 tasksets
模块中导入 generate
模块,所以任务集
包括以下导入:
Sometimes I want to import the generate
module from within the tasksets
module when I run the tasksets
module as a script, so tasksets
includes the following import:
import generate
有时我想从 training
模块中导入 tasksets
模块,因此 training
包含以下导入:
Other times I want to import the tasksets
module from within the training
module, so training
contains the following import:
import tasksets
但是,此设置给我带来了问题.当我将 tasksets
作为脚本运行时, tasksets
可以很好地导入 generate
,但是如果我在其中导入 tasksets
,则会引发错误当我将 training
作为脚本运行时, training
(我认为是因为 training
在脚本中找不到 generate
作为脚本默认路径).我尝试过使用 __ init __.py
文件,相对导入等查看各种其他StackOverflow问题和答案.目前,我的解决方法是在 tasksets中使用以下几行代码>:
However, this setup is giving me problems. tasksets
can import generate
fine when I run tasksets
as a script, but throws an error if I import tasksets
inside training
when I run training
as a script (I think because training
can't find generate
as a script within the default path). I've tried looking at all sorts of other StackOverflow questions and answers, using __init__.py
files, relative imports, etc. Currently, my workaround is to use the following lines inside tasksets
:
if __name__ == "__main__": import generate
else: from data import generate
但这感觉不对(我的IDE也都不喜欢).请有人能解释一下如何使用正确的 __ init __.py
文件分类和导入语句,以便我在运行 tasksets
时可以导入 generate
脚本,并且在将 training
作为脚本运行时还导入 tasksets
?
But this doesn't feel right (and my IDE don't like it neither). Please can someone explain how to use the right assortment of __init__.py
files and import statements such that I can import generate
when running tasksets
as a script, and also import tasksets
when running training
as a script?
推荐答案
您最好使用经典的Python模块/包体系结构.
You better use a classical Python module / package architecture.
projectname/
__init__.py
__main__.py
data/
__init__.py
generate.py
tasksets.py
要使用您的应用,请进入 projectname/../
目录(上一级 projectname/
)并运行 python -m projectname
.这将执行 projectname/__ main __.py
.
To use your app, go into projectname/../
directory (one level upper projectname/
) and run python -m projectname
. This will execute projectname/__main__.py
.
在 __ main __.py
中,您将编写如下内容:
In __main__.py
you will write something like:
from projectname.data import generate
from projectname.data import tasksets
if __name__ == '__main__':
generate.foo()
tasksets.bar()
- 您将使用绝对导入路径(以模块名称和点号,即
projectname.
开头). - 如果__name__ =='__main __' ,您将从
-
__ main __.py
将是您的应用程序/脚本的唯一入口点.
导入子模块
- You will use absolute import path (starting by your module name and a dot,
projectname.
) - You will import your submodules out of the
if __name__ == '__main__'
__main__.py
will be the only entry-point of your app/script.
在任何其他文件中,您将使用相同的语法和路径来导入其他模块:
In any other file, you will use the same syntax and paths to import other modules:
data/generate.py
:
from projectname.data import tasksets
def foo():
print('SPAM!')
tasksets.bar()
我不太喜欢的东西,但我不确定有人能拒绝它,
在您的 projectname/__ init __.py
文件中,您可以编写:
In your projectname/__init__.py
file you can write:
from projectname.data import generate
from projectname.data import tasksets
因此,您的两个子模块将被导入到主作用域 __ init __.py
中,因此您可以从该作用域中导入子模块,例如
So your two submodules will be imported into your main scope __init__.py
, so you are able to import the submodules from this scope, like
data/generate.py
:
from projectname import generate
但是再次,我不是很喜欢这种方式(因为显式比隐式好.)
But again, I don't really enjoy this way of doing (because Explicit is better than implicit.)
最后但并非最不重要
- 您还可以使用
python projectname/__ main __.py
命令,但我仍然建议python -m projectname
- 您可以使用 setuptools setup.py 文件>在系统上安装"您的应用程序,然后只需运行
projectname
命令即可运行它.
- You can also use
python projectname/__main__.py
command, but I still recommendpython -m projectname
- You can create a
setup.py
file using setuptools to "install" your app on your system and simply runprojectname
command to run it.
这篇关于从不同层次的层次导入Python模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!