从__init__中的Python子模块导入方法,但不是子模块本身

尼科·施洛默(NicoSchlömer)

我有一个具有以下结构的Python模块:

mymod/
    __init__.py
    tools.py
# __init__.py
from .tools import foo
# tools.py
def foo():
    return 42

现在,当时import mymod,我看到它具有以下成员:

mymod.foo()
mymod.tools.foo()

但是我不希望后者。它只会污染名称空间。

有趣的是,如果tools.py被称为,foo.py您将得到想要的:

mymod.foo()

(显然,这仅在每个文件只有一个功能的情况下有效。)

如何避免导入tools需要注意的是把foo()__init__.py是不是一种选择。(实际上,有很多功能foo绝对会使文件混乱。)

user2357112支持Monica

mymod.tools属性的存在对于维持导入系统的正常功能至关重要。Python导入的常规不变式之一是,如果在x.y中注册了模块sys.modules,则该x模块具有y引用该x.y模块属性不然的话

import x.y
x.y.y_function()

中断,并且取决于Python版本,甚至

from x import y

会破裂。即使您不认为自己会做任何会破坏的事情,其他工具和模块也要依赖这些不变式,而尝试删除该属性会导致一系列兼容性问题,这些问题根本不值得。


尝试tools不让其显示在mymod模块的命名空间中,就像是尝试不使“私有”(前导下划线)属性显示在对象的命名空间中。这并不是设计Python的工作方式,而试图迫使它以这种方式工作会导致更多问题,而不是解决的问题。

前导下划线约定不仅针对实例变量。您可以在tools模块前面加上下划线,将其重命名为_tools这将防止它被from mymod import *导入拾取(除非您明确地将其放入__all__列表中),并且它将更改IDE和linters如何对待直接访问它的尝试。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

TOP 榜单

热门标签

归档