Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从_init__中的Python子模块导入方法,但不导入子模块本身_Python_Python Import_Python Module - Fatal编程技术网

从_init__中的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() (显然,这仅在每个文件只有一个函数的情况下有

我有一个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()
(显然,这仅在每个文件只有一个函数的情况下有效。)


如何避免导入
工具
?请注意,将
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存储库,看看项目是如何组织的。