gpt4 book ai didi

python - 为什么 from ... import ... 语句包含隐式导入?

转载 作者:行者123 更新时间:2023-12-01 00:09:45 24 4
gpt4 key购买 nike

给定一个包:

package/
├── __init__.py
└── module.py

__init__.py:

from .module import function

模块.py:

def function():
pass

可以导入包并打印其 namespace 。

python -c 'import package; print(dir(package))'

['__builtins__', ..., 'function', 'module']


问题:

为什么 package的命名空间包含 module当只有 function被导入 __init__.py ?

我本来希望 package的命名空间将只包含 function而不是 module . Documentation 中也提到了这种机制。 ,

"When a submodule is loaded using any mechanism (e.g. importlib APIs, the import or import-from statements, or built-in __import__()) a binding is placed in the parent module’s namespace to the submodule object."



但并没有真正的动力。对我来说,这个选择似乎很奇怪,因为我认为子模块是结构包的实现细节,并且不期望它们成为 API 的一部分,因为结构可以改变。

我也知道“Python 是为成年人所用的”,并且不能真正对用户隐藏任何东西。但我会争辩说,将子模块名称绑定(bind)到包的范围会使用户不太清楚什么是 API 的实际部分以及可以更改的内容。

为什么不用 __sub_modules__属性左右使用户可以访问子模块?这个设计决定的原因是什么?

最佳答案

您说您将子模块视为实现细节。这不是子模块背后的设计意图;它们可以并且非常普遍地是包的公共(public)接口(interface)的一部分。导入系统旨在促进对子模块的访问,而不是阻止访问。

加载子模块会将绑定(bind)放置到父模块的命名空间中,因为这是访问模块所必需的。例如,在以下代码之后:

import package.submodule

表达式 package.submodule必须评估子模块的模块对象。 package评估为包的模块对象,因此该模块对象必须有 submodule引用子模块的模块对象的属性。

此时,您几乎肯定在想,“嘿, from .submodule import function 没有理由必须做同样的事情!”它做同样的事情是因为这个属性绑定(bind)是子模块初始化的一部分,它只发生在第一次导入时,并且无论哪种导入触发它都需要进行相同的设置。

这不是一个非常有力的理由。通过足够的更改和重新调整,导入系统绝对可以按照您期望的方式设计。它不是这样设计的,因为设计师的优先级与你不同。 Python 的设计很少关心隐藏事物或支持任何隐私概念。

关于python - 为什么 from ... import ... 语句包含隐式导入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59646065/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com