我想知道为什么在python包中保存子模块的目录(子包)在导入包时显示为符号。例如,如果我有这个包:
PyModTest/ Top-level package
__init__.py Initialize the package
Source/ Subpackage holding source files
__init__.py
WildMod.py Submodule containing a function: 'WildFunc'
顶层__init__.py看起来像这样:
#!/usr/bin/env python
from Source.WildMod import WildFunc
,为了完整起见,较低级别的__init__.py看起来像这样:
#!/usr/bin/env python
__all__ = ["WildMod"]
好,现在我打开解释器,导入模块,并查看符号:
>>> import PyModTest
>>> dir(PyModTest)
['Source', 'WildFunc', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']
看,'Source'模块显示出来了,尽管我从未特别导入过它!
我想看到的唯一符号(除了私有符号)是我的'WildFunc'。有没有办法隐藏"源"包?
有两点需要注意:
- 在Python中,模块是实际的对象,它们名称之间出现的点表示实际的属性访问
- 您正在进行相对导入,这意味着
Source
实际上是PyModTest.Source
(感谢TokenMacGuy指出这一点)
PyModTest.Source.WildMod.WildFunc
, Python必须
- 导入
PyModTest
(你已经做了) - 检查并查看它是否有一个名为
Source
的属性,如果没有,通过从PyModTest/Source/__init__.py
导入创建该属性 - 检查并查看是否有一个名为
WildMod
的属性,如果没有,通过从PyModTest/Source/WildMod.py
导入创建该属性 - 检查并查看是否有一个名为
WildFunc
的属性(它确实有)
在PEP 302和Python语言参考中讨论了一些相关细节。
在该机制的更深处,带点的名称导入由它的组件。对于"
import spam.ham
",首先是"import spam
"完成后,只有当成功时,才会将"ham
"作为子模块导入
如果您不希望有一个名为Source
的变量,这很容易修复:在导入函数后只使用del Source
。但是请记住,它将阻止以后运行的任何代码访问PyModTest.Source.<anything>
(WildFunc
除外,因为您已经保存了对CC_17的引用)。我绝对建议忽略对Source
的引用,而不是删除它,因为它不会伤害任何东西。