从_init__中的Python子模块导入方法,但不导入子模块本身
我有一个Python模块,其结构如下:从_init__中的Python子模块导入方法,但不导入子模块本身,python,python-import,python-module,Python,Python Import,Python Module,我有一个Python模块,其结构如下: mymod/ __init__.py tools.py 初始化 from.tools导入foo #tools.py def foo(): 返回42 现在,当导入mymod时,我看到它有以下成员: mymod.foo() mymod.tools.foo() 但我不想要后者;它只是污染了名称空间 有趣的是,如果tools.py被称为foo.py您就可以得到您想要的: mymod.foo() (显然,这仅在每个文件只有一个函数的情况下有
mymod/
__init__.py
tools.py
初始化
from.tools导入foo
#tools.py
def foo():
返回42
现在,当导入mymod时,我看到它有以下成员:
mymod.foo()
mymod.tools.foo()
但我不想要后者;它只是污染了名称空间
有趣的是,如果tools.py
被称为foo.py
您就可以得到您想要的:
mymod.foo()
(显然,这仅在每个文件只有一个函数的情况下有效。)
如何避免导入
工具
?请注意,将foo()
放入\uuuu init\uuuu.py
不是一个选项。(实际上,有许多函数,如foo
,它们绝对会把文件弄得乱七八糟。)尝试将其放入\uuuu init\uuuuuuuuy.py
文件中:
from .tools import foo
del tools
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
模块的命名空间中,有点像试图不使“private”(前导下划线)属性显示在对象的命名空间中。这不是Python的工作方式,试图强迫它以这种方式工作会导致比它解决的问题更多的问题
前导下划线约定不仅仅适用于实例变量。您可以使用前导下划线标记
工具
模块,将其重命名为\u工具
。这将防止它被mymod import*imports的获取(除非您明确地将它放入\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,当您像这样导入软件包时,它才可用:
导入mymod
您将有权访问\uuuuu init\uuuu
文件中定义的所有内容以及此软件包的所有模块:
导入mymod
#引用模块
mymod.tools
#引用模块的成员
mymod.tools.foo
#以及此软件包中的任何其他模块
mymod.tools.subtools.func
当您导入foo
inside\uuuu init\uuuu
时,您只是在那里使foo
可用,就像您在那里定义了它一样,但当然,您在工具中定义了它,这是一种组织包的方法,因此现在既然您在\uu init\uuu
内部导入了它,您可以:
导入mymod
mymod.foo()
或者您可以单独导入foo
:
从mymod导入foo
foo()
但是您可以导入foo
,而无需在\uuuu init\uuuu
中提供它,您可以执行与上面示例完全相同的以下操作:
从mymod.tools导入foo
foo()
您可以使用这两种方法,它们都是正确的,在所有这些示例中,您不会像您看到的那样使用mymod.tools访问foo
。foo
具有名称空间,因此您可以在其他模块中定义多个foo
。如果我理解您的操作,这在内容上与我之前的问题有点类似:,看看有没有什么可以用的。基本上,我被告知我所期望的是非语法化的,我应该对mymod.tools.foo()
感到满意。这在技术上是可行的,但会产生严重的副作用,超过从名称空间中删除一个名称的任何微小好处。这不是我想要的。我只想要mymod.foo()
,因为有太多的foo
s,我想把它们放在单独的文件中,而不是把它们塞进\uuuu init\uuuuuuuuuuuy.py
@NicoSchlömer你不必把它们全部导入\uuu init\uuuuuuuuuuu
文件,你只需要像mymod.foo()那样直接导入你想要使用的文件
,您可以导入或通过引用它们来使用它们,如mymod.submod.foo()
。通过导入mymod
您并没有使所有子模块及其成员都可用,您可以在需要时引用它们。所谓“导入”是指复制并粘贴到其中?不,太多了,甚至是我想对外提供的。我必须将它们放在单独的文件中。@NicoSchlömer不,我不是说复制和粘贴,我是说使用import
关键字import whatever.you.want
,我建议您在Github上查看一些流行的Python存储库,看看项目是如何组织的。