试图更好地理解模块和包导入

Trying to understand module and package imports better

我正在尝试更好地理解 Python 如何从包中识别和定义模块。

以 tkinter 为例,当我查看 anaconda>Lib>tkinter 下提供的文件时,没有 tkinter.py 文件,如果我对 tkinter 目录中的文件进行文本搜索,我会这样做看不到作为模块的 tkinter 是如何定义的,但我能够导入它并使用它。会很感激解释以了解我所缺少的吗?也许它是在 .pyc 文件中定义的?

我不使用anaconda;我的只是 python.org 的标准安装。我的 Lib 目录中确实有一个 tkinter 文件夹 -- 但是 没有 tkinter.py。与任何包一样,该目录中有一个 __init__.py 文件,该文件中的内容如下:

import _tkinter # If this fails your Python may not be configured for Tk

这表明我的 Python 应该使用提供必要支持的 _tkinter 的 C 库实现构建。

确定没有tkinter目录吗?

更新

当您 import tkinter 时,您正在导入一个 在这种情况下,因为 tkinter 是一个包含 __init__.py 文件的目录。结果是 __init__.py 被加载并执行。该文件中的全局名称成为 tkinter 模块的属性。例如,该文件中的函数 _join 可以作为 tkinter._join 访问。但也因为在该文件中有一个 import sys 语句,您甚至可以访问 tkinter.sys。或者,如果您愿意,可以说 from tkinter import sys.

不过你也可以说from tkinter import messagebox。为什么?没错,__init__.py 中没有 messagebox 定义,但是 tkinter 目录中有一个 messagebox.py 文件,这就是其他子模块可以加载的方式。

__init__.py 文件必须存在于所有包的目录中,并且将目录定义为包,它包含在导入包名称时初始化包的代码。它可能包含导入包的某些常用子模块的代码。很多时候文件只是空的,但需要存在。