【问题标题】:python import package - subpackage should not show up in symbol tablepython导入包 - 子包不应该出现在符号表中
【发布时间】:2012-01-22 10:12:39
【问题描述】:

我想知道为什么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__']

看,“源”模块出现了,尽管我从未专门导入它!

我想看到的唯一符号(除了私有符号)是我的“WildFunc”。有没有办法隐藏“源”包?

【问题讨论】:

    标签: python


    【解决方案1】:

    这里需要注意两点:

    • 在 Python 中,模块是实际的对象,出现在它们名称之间的点表示实际的属性访问
    • 您正在进行相对导入,这意味着 Source 实际上是 PyModTest.Source(感谢 TokenMacGuy 指出这一点)

    所以:为了导入PyModTest.Source.WildMod.WildFunc,Python 必须

    1. import PyModTest(你已经完成了)
    2. 检查它是否有一个名为Source的属性,如果没有,则通过从PyModTest/Source/__init__.py导入来创建该属性
    3. 检查它是否有一个名为WildMod 的属性,如果没有,则通过从PyModTest/Source/WildMod.py 导入来创建该属性
    4. 检查它是否有一个名为 WildFunc 的属性(确实如此)

    PEP 302Python language reference 讨论了一些相关细节。

    在机制的更深处,一个虚线名称导入被拆分为 它的组成部分。对于“import spam.ham”,首先是“import spam” 完成,并且只有在成功时才会将“ham”作为子模块导入 “spam”。

    如果您不想有一个名为Source 的变量,这很容易解决:只需在导入函数后del Source。但请记住,它将阻止以后运行的任何代码访问PyModTest.Source.<anything>WildFunc 除外,因为您已经保存了对它的引用)。我绝对会建议忽略对Source 的引用,而不是删除它,因为它不会伤害任何东西。

    【讨论】:

    • 太棒了,说得通。感谢您对“del Source”的建议:)
    • SourcePyModTest 的子包,隐式导入会默默地转换为from PyModTest.Source import ...,因此必须将Source 模块添加为PyModTest 模块的属性。如果在PyModTest 包之外找到Source(不太可能,子包优先于sys.path),则不会发生这种情况。为避免混淆自己和他人,请始终选择绝对导入。
    • @TokenMacGuy:啊,很好。不知何故,我错过了这是一个相对导入的事实。
    猜你喜欢
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-24
    • 1970-01-01
    • 2017-02-25
    • 1970-01-01
    • 2020-07-19
    相关资源
    最近更新 更多