Python 导入 - 为什么需要主包名称?
Python imports - why main package name is required?
我想知道为什么我需要在创建项目目录结构的 import
语句中包含主目录名称。
我的项目结构
.
├── main.py
├── myModel
│ ├── __init__.py
│ ├── loader
│ │ ├── __init__.py
│ │ └── dataset_loader.py
│ └── models
│ ├── __init__.py
│ ├── static_model.py
│ └── task_model.py
└── tree.txt
main.py
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
没有用,所以我认为它需要存在。
其次,为什么我可以直接从 loader
调用 fun
而不是使用完全限定路径?
我读了something on the web。但我仍然无法理解为什么会这样。
绝对导入,例如 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
中描述的模块绑定到名称 x
,并确保 x
具有属性 y
,作为 x.py
/__init__.py
中定义的属性,或作为 x/y.py
. 中的子模块
from x import y
将 x.py
/x/__init__.py
或 x/y.py
中的属性或子模块 y
绑定到名称 y
。此选项加载,但不会让您访问 x
.
当您 运行 from myModel import loader
时,您会得到一个模块对象 loader
,它具有可调用属性 fun
.
我想知道为什么我需要在创建项目目录结构的 import
语句中包含主目录名称。
我的项目结构
.
├── main.py
├── myModel
│ ├── __init__.py
│ ├── loader
│ │ ├── __init__.py
│ │ └── dataset_loader.py
│ └── models
│ ├── __init__.py
│ ├── static_model.py
│ └── task_model.py
└── tree.txt
main.py
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
没有用,所以我认为它需要存在。
其次,为什么我可以直接从 loader
调用 fun
而不是使用完全限定路径?
我读了something on the web。但我仍然无法理解为什么会这样。
绝对导入,例如 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
中描述的模块绑定到名称x
,并确保x
具有属性y
,作为x.py
/__init__.py
中定义的属性,或作为x/y.py
. 中的子模块
from x import y
将x.py
/x/__init__.py
或x/y.py
中的属性或子模块y
绑定到名称y
。此选项加载,但不会让您访问x
.
当您 运行 from myModel import loader
时,您会得到一个模块对象 loader
,它具有可调用属性 fun
.