为什么要删除 __init__.py 中的模块?
Why delete modules in __init__.py?
我正在对 PyTorch 源代码进行一些研究。在 this file 中,作者实际上删除了模块。
from .adadelta import Adadelta # noqa: F401
from .adagrad import Adagrad # noqa: F401
from .adam import Adam # noqa: F401
del adadelta
del adagrad
del adam
这样做的理由是什么?
这是一种在不使子模块成为 public API 的一部分的情况下将功能分解为子模块的方法。导入系统的一个怪癖是 this sort of relative import ends up putting the submodules in the parent's namespace,因此用户可以执行以下操作:
import torch.optim
然后访问 torch.optim.adadelta
的属性,而无需显式导入 torch.optim.adadelta
。虽然一些 Python 内置包以这种方式工作,但它不会被撤消,因为太多人无意中依赖它(例如,只有 import os
的人,然后使用 os.path
APIs), 通常最好避免这种数据泄漏。导入 torch.optim
应该只提供对列出的特定名称的访问,而不保证将自动导入哪些子模块。
通过这样做,人们不会意外地依赖于仅导入 torch.optim
后能够使用 torch.optim.adadelta
,因此开发人员可以自由重构它以移动特定 类 和周围的其他 API,没有做出特别的努力来确保 import torch.optim
也导入所有这些子模块只是为了保留执行 improper/incomplete 导入的代码的行为。
我正在对 PyTorch 源代码进行一些研究。在 this file 中,作者实际上删除了模块。
from .adadelta import Adadelta # noqa: F401
from .adagrad import Adagrad # noqa: F401
from .adam import Adam # noqa: F401
del adadelta
del adagrad
del adam
这样做的理由是什么?
这是一种在不使子模块成为 public API 的一部分的情况下将功能分解为子模块的方法。导入系统的一个怪癖是 this sort of relative import ends up putting the submodules in the parent's namespace,因此用户可以执行以下操作:
import torch.optim
然后访问 torch.optim.adadelta
的属性,而无需显式导入 torch.optim.adadelta
。虽然一些 Python 内置包以这种方式工作,但它不会被撤消,因为太多人无意中依赖它(例如,只有 import os
的人,然后使用 os.path
APIs), 通常最好避免这种数据泄漏。导入 torch.optim
应该只提供对列出的特定名称的访问,而不保证将自动导入哪些子模块。
通过这样做,人们不会意外地依赖于仅导入 torch.optim
后能够使用 torch.optim.adadelta
,因此开发人员可以自由重构它以移动特定 类 和周围的其他 API,没有做出特别的努力来确保 import torch.optim
也导入所有这些子模块只是为了保留执行 improper/incomplete 导入的代码的行为。