从不同层次的层次导入Python模块 [英] Importing Python modules from different levels of hierarchy

查看:49
本文介绍了从不同层次的层次导入Python模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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()

  1. 您将使用绝对导入路径(以模块名称和点号,即 projectname.开头).
  2. 如果__name__ =='__main __'
  3. ,您将从导入子模块
  4. __ main __.py 将是您的应用程序/脚本的唯一入口点.
  1. You will use absolute import path (starting by your module name and a dot, projectname.)
  2. You will import your submodules out of the if __name__ == '__main__'
  3. __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.)

最后但并非最不重要

  • You can also use python projectname/__main__.py command, but I still recommend python -m projectname
  • You can create a setup.py file using setuptools to "install" your app on your system and simply run projectname command to run it.

这篇关于从不同层次的层次导入Python模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆