python - 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
而不是使用完整的路径?
我在网上读到了一些东西。但我仍然无法理解为什么会发生这种情况。
解决方案
绝对进口,喜欢import x.y.z
或from 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
您使用的形式:
import x
将描述的模块绑定到名称x.py
或x/__init__.py
名称x
import x.y
x.py
将描述的模块绑定x/__init__.py
到 namex
,并确保它x
具有属性,或者作为/中y
定义的属性,或者作为 中的子模块。x.py
__init__.py
x/y.py
from x import y
将属性或子模块y
从x.py
/x/__init__.py
或绑定x/y.py
到 namey
。此选项加载,但不允许您访问x
.
运行时,您会得到一个具有可调用属性from myModel import loader
的模块对象。loader
fun
推荐阅读
- lightgbm - 二进制:LightGBM 中的逻辑类参数
- sql - SQL - 重复需要多行
- c# - 在 RichTextBox C# 中添加多个非 url 超链接,为每个超链接抛出一个事件
- javascript - dc.js 使用两组的箱线图缩减器
- numpy - 改变学习率后 SGD 发散
- laravel - 会话开始失败 Laravel
- r - 在 R 中,如何检查一列中的记录是否与某个值匹配,如果匹配,则更改另一列中的记录?
- r - choose.files() 默认为最后使用的目录
- swift - Swift:在下一次加载之前等待firestore加载
- json - Json Path - 过滤列表列表