【问题标题】:Import All Does Not Import All全部导入 不全部导入
【发布时间】:2015-10-11 12:37:35
【问题描述】:

import 声明:

from tkinter import *

不导入tkinter.filedialog。为什么没有?

【问题讨论】:

标签: python tkinter namespaces python-import


【解决方案1】:

tkinter 是一个包,当做from tkinter import * 时,它会为tkinter 包导入__init__.py 中定义的所有名称,以及仅在__all__ 中定义的模块和子包__init__.pytkinter 包。

在我的 Python 3.4 中,tkinter/__init__.py 中没有定义 __all__,因此它不会从其中导入任何模块(如 filedialog)。

这在the documentation -中有解释

唯一的解决方案是包作者提供包的显式索引。 import 语句使用以下约定:如果包的 __init__.py 代码定义了一个名为 __all__ 的列表,则它被视为遇到 from package import * 时应导入的模块名称列表。

如果未定义__all__,则from sound.effects import *语句不会将sound.effects包中的所有子模块导入当前命名空间;它只确保包 sound.effects 已被导入(可能在__init__.py 中运行任何初始化代码),然后导入包中定义的任何名称。这包括__init__.py 定义的任何名称(以及显式加载的子模块)。

【讨论】:

  • 这似乎与这个高度评价的answer 相矛盾。 如果上面的 all 被注释掉,这段代码将执行到完成,因为 import * 的默认行为是从给定的命名空间导入所有不以下划线开头的符号. filedialog 不以下划线开头。
  • 他们谈论的是单个模块,这对于包来说不是这样(就像我强调的那样,tkinter 是一个包,它不会自动从包中导入模块(如果 @987654341 @ 未指定)。正如我在答案中链接的文档中也很好解释的那样。
  • 包基本上是可以包含其他包/模块的目录。模块是单个 .py 文件。如果您想了解更多关于包的信息,this 将是一个不错的起点
【解决方案2】:

通常,从from <package> import * 导入的值取决于该包的__init__ 文件的__all__ 列表中指定的值。

无法导入filedialog 意味着它不包含在tkinter __init__ 文件的__all__ 列表中。


评估一个包是否“导出”某些子模块的快速方法是评估它是否在您import 之后具有__all__ 属性。如果是,它将返回可用的子模块,如果不是,则会引发 Attribute Error

例如,对于像scipy这样的包:

import scipy
print(scipy.__all__) # prints all contents.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-12
    • 2013-08-22
    • 1970-01-01
    • 2013-06-09
    • 1970-01-01
    • 1970-01-01
    • 2016-07-20
    • 2021-11-28
    相关资源
    最近更新 更多