首页 > 解决方案 > Python 导入 - 为什么需要主包名称?

问题描述

我想知道为什么我需要在import创建项目目录结构的语句中包含主目录名称。

我的项目结构

.
├── main.py
├── myModel
│   ├── __init__.py
│   ├── loader
│   │   ├── __init__.py
│   │   └── dataset_loader.py
│   └── models
│       ├── __init__.py
│       ├── static_model.py
│       └── task_model.py
└── tree.txt

主文件

from myModel import loader
from myModel import models

loader.fun ()
loader.dataset_loader.fun ()

myModel/__init__.py

import myModel.models
import myModel.loader

myModel/loader/__init__.py

from myModel.loader.dataset_loader import *

myModel/models/__init__.py

from myModel.models.static_model import StaticModel

我的第一个问题是为什么我myModel什至需要放在myModel目录的子文件夹中。我试图删除它,但import没有奏效,所以我认为它需要在那里。

其次,为什么我可以fun直接调用loader而不是使用完整的路径?

我在网上读到了一些东西。但我仍然无法理解为什么会发生这种情况。

标签: pythonpython-import

解决方案


绝对进口,喜欢import x.y.zfrom x.y import z需要x在你的道路上。在您的特定情况下,myModel由于您的工作目录,它位于路径上。子包不在路径上,因此只能通过重复根包来访问。

更直观的方法可能是使用相对路径。这是可能的,因为您的所有文件都存在于带有文件的适当包中__init__。请记住,相对路径意味着您拥有设计为存在于包结构中而不是独立存在的模块。否则,当您尝试将某些模块作为独立脚本运行时,最终可能会导致错误。

更改myModel/__init__.py为:

from . import models
from . import loader

使.导入相对。请注意,我没有建议更改main.py,因为它位于您的包之外。添加更多点可以让您在文件层次结构中上升更多级别。

更改myModel/loader/__init__.py

from .dataset_loader import *

myModel/models/__init__.py_

from .static_model import StaticModel

一条import语句在您的本地命名空间(通常是您正在执行它的模块)中绑定一个名称。绑定的名称取决于import您使用的形式:

  1. import x将描述的模块绑定到名称x.pyx/__init__.py名称x
  2. import x.yx.py将描述的模块绑定x/__init__.py到 name x,并确保它x具有属性,或者作为/中y定义的属性,或者作为 中的子模块。x.py__init__.pyx/y.py
  3. from x import y将属性或子模块yx.py/x/__init__.py或绑定x/y.py到 name y。此选项加载,但不允许您访问x.

运行时,您会得到一个具有可调用属性from myModel import loader的模块对象。loaderfun


推荐阅读