除了__file__ 以外,python还有哪些内置变量?一文详细介绍!
Python 中这些前后都有双下划线的变量,通常被称为 "Magic Variables"(魔法变量) 或 "Dunder Variables" (Double Underscore)。
它们不是让你随意修改的变量,而是 Python 解释器自动维护的、用于存储**元数据(Metadata)**或控制程序行为的特殊属性。
为了让你更容易理解,我将它们分为三类:最常用的核心变量、模块与包相关、以及类与调试相关。
第一类:最常用的核心变量 (必须掌握)
这两个是你写 Python 脚本时几乎每天都会遇到的。


第二类:文件路径与包管理 (类似 __file__)
这一类主要用于定位“我在哪”、“我是谁的部下”。

第三类:对象内部与调试 (进阶黑魔法)
这些变量通常用于“自省”(Introspection),即代码在运行时查看自己的状态。

第四类:全局系统变量

总结:最实用的速查表
虽然列了这么多,但实际开发中,90% 的场景你只需要关注下面这 4 个:
-
__name__: 用来写入口函数if __name__ == "__main__":。 -
__file__: 用来定位资源文件的路径。 -
__init__.py: (虽然是文件不是变量) 用来把文件夹变成包。 -
__dict__: 调试时用来查看对象内部结构。
你可以试着在你之前的那个代码里加上这句,看看输出了什么,加深理解:
print(f"当前运行的模块名: {__name__}") print(f"当前文件的文档: {__doc__}")
追问:上面总结3标红的 __init__.py: (虽然是文件不是变量) 用来把文件夹变成包,详细解释。
我们可以把 __init__.py 想象成一个文件夹的 “身份证” 或者 “前台接待员”。
它的核心作用就是告诉 Python:“我这个文件夹不是用来存杂物的,我是一个可以在代码里被导入(Import)的包(Package)。”
下面我用三个具体的场景来解释它的作用。
场景 1:把“普通文件夹”变成“包” (身份认证)
假设你的项目目录是这样的:
my_project/ ├── main.py └── utils/ <-- 这是一个普通文件夹 ├── math.py <-- 这里面有个 add() 函数 └── string.py
如果你想在 main.py 里直接导入 utils,像这样:import utils。
-
没有
__init__.py:Python (旧版本) 会报错,因为它觉得utils只是个普通存放文件的目录,不是代码模块。 -
有
__init__.py:你在utils文件夹里新建一个空的__init__.py文件。Python 看到它,就会承认utils是一个包,允许你导入它。
注意:虽然 Python 3.3+ 即使没有这个文件也能勉强导入(称为 Namespace Package),但为了规范和兼容性,大家依然习惯加上它。
场景 2:对外“偷懒” (简化导入路径) —— 这是最常用的功能
这是 __init__.py 最大的威力所在:它可以把深层级的功能“提拔”到顶层。
现状(很繁琐): 假设你的 utils/math.py 里有一个很牛的函数叫 super_add。 如果没有配置 __init__.py,别的程序员想用这个函数,必须写很长的导入语句:
# main.py from utils.math import super_add # 必须精确找到文件 super_add(1, 1)
改进(用 __init__.py 简化): 你可以编辑 utils/__init__.py,在里面写一行代码,把里面的函数“暴露”出来:
# utils/__init__.py 的内容: from .math import super_add # 从当前目录的 math 文件里,导入 super_add
结果(很优雅): 现在,使用者在 main.py 里只需要导入包名,就能直接用函数了,感觉这个函数好像就在 utils 根目录下一样:
# main.py import utils utils.super_add(1, 1) # 哇!路径变短了!
这就好比: 公司里虽然办事的人在里面的办公室(math.py),但通过前台(__init__.py)转接,客户(main.py)直接找前台就能办业务,不需要走进具体的办公室。
场景 3:初始化代码 (开机自启)
因为 __init__.py 本身是一个 Python 文件,当这个包被第一次导入时,这个文件里的代码会自动运行。
你可以利用这一点做一些“初始化”工作,比如加载配置、检查环境,或者仅仅是打印个日志。
# utils/__init__.py 的内容: print("正在初始化 utils 包...") DB_URL = "mysql://..."
当你在 main.py 里写 import utils 时,控制台会立刻打印出 "正在初始化 utils 包...",并且你可以直接使用 utils.DB_URL。
总结
__init__.py 的三个核心作用:
-
挂牌营业:告诉 Python 这个文件夹是一个包。
-
暴露接口:把文件夹深处的好东西(类、函数)直接引入到顶层,方便外部调用(这是最主要用途)。
-
初始化:在包导入时自动运行一些准备代码。
一句话口诀: 只要你想让一个文件夹里的代码能被 import 优雅地使用,就给它塞一个 __init__.py。

浙公网安备 33010602011771号