Python 中 __name__ 属性详解:模块身份与 import as 用法

48 阅读6分钟

Python 中 __name__ 属性详解:模块身份与 import as 用法

深入理解模块内置属性,掌握模块化编程核心技巧
作者:errorPage | 发布时间:2025-12-07

一、引言

在 Python 模块化编程中,__name__ 是一个看似简单却至关重要的内置属性。它就像模块的“身份证”,决定了模块的运行身份——是作为主程序直接运行,还是被其他模块导入复用。

而在实际开发中,我们常使用 import 模块名 as 别名 简化代码书写,但很多开发者会疑惑:导入时指定别名,会不会改变模块的 __name__ 属性?本文将带你全面拆解 __name__ 的核心逻辑,以及 import as 的使用细节。

二、__name__ 属性:模块的“身份标识”

__name__ 是 Python 模块(.py 文件)的内置魔法属性(前后各两个下划线),无需手动定义,模块被解释器加载时会自动赋值。其取值规则仅与「模块的运行方式」相关,与导入方式无关。

2.1 __name__ 的两种核心取值场景

无论模块的文件名是什么,__name__ 只有两种可能的取值,对应两种运行场景:

运行方式 __name__ 的取值 适用场景
直接运行当前模块 "__main__"(固定值) 作为程序入口、测试模块功能
模块被其他文件导入 模块的文件名(不含 .py 后缀) 复用模块中的函数、类、变量

2.2 直观示例:验证 __name__ 的取值

我们通过两个文件的互动,直观感受 __name__ 的变化:

步骤 1:创建被导入模块 test_module.py

# test_module.py print(f"我是 test_module.py,我的 __name__ = {__name__}") # 定义一个供复用的函数 def add(a, b): return a + b

场景 A:直接运行 test_module.py

终端执行 python test_module.py,输出:

我是 test_module.py,我的 __name__ = __main__

结论:模块直接运行时,__name__ 固定为 "__main__"

场景 B:导入 test_module 到其他文件

创建 main.py,导入 test_module 并使用其函数:

# main.py # 导入 test_module 模块 import test_module # 调用导入模块的函数 result = test_module.add(10, 20) print(f"调用 test_module.add 结果:{result}") print(f"我是 main.py,我的 __name__ = {__name__}")

终端执行 python main.py,输出:

我是 test_module.py,我的 __name__ = test_module 调用 test_module.add 结果:30 我是 main.py,我的 __name__ = __main__

结论:

  • 被导入的模块(test_module.py):__name__ = 模块文件名(test_module)
  • 直接运行的模块(main.py):__name__ 依然是 "__main__"

三、__name__ 的核心用途:主程序入口

Python 开发者的必备写法:if __name__ == "__main__":。通过这个判断,让模块实现「双重身份」——既能被导入复用,又能直接运行测试。

核心价值:模块内的测试代码、程序入口逻辑,只有在「直接运行该模块」时才执行;被其他模块导入时,这部分代码会被忽略,不影响复用。

3.1 实践示例:优化 test_module.py

给 test_module.py 添加主程序入口,用于测试 add 函数:

# test_module.py print(f"我是 test_module.py,我的 __name__ = {__name__}") def add(a, b): return a + b # 主程序入口:仅直接运行时执行 if __name__ == "__main__": print("=== 直接运行 test_module,执行测试 ===") test_result = add(2, 3) print(f"add(2,3) 的测试结果:{test_result}") # 输出 5

3.2 效果验证

情况 1:直接运行 test_module.py

我是 test_module.py,我的 __name__ = __main__ === 直接运行 test_module,执行测试 === add(2,3) 的测试结果:5

✅ 测试代码正常执行。

情况 2:导入 test_module 到 main.py 运行

我是 test_module.py,我的 __name__ = test_module 调用 test_module.add 结果:30 我是 main.py,我的 __name__ = __main__

✅ 测试代码被忽略,不影响模块复用。

四、import ... as ...:别名不改变 __name__ 本质

在开发中,我们常使用 import 模块名 as 别名(如 import pandas as pd),核心目的是简化代码书写或避免模块名冲突。但很多人会疑惑:别名会改变模块的 __name__ 吗?

关键结论import ... as ... 仅为模块在当前文件中创建一个「临时引用别名」,不会修改模块本身的任何属性(包括 __name__)。模块的 __name__ 依然由「模块文件名」和「运行方式」决定。

4.1 示例:别名导入时的 __name__

创建 main_with_alias.py,用别名导入 test_module:

# main_with_alias.py # 给 test_module 起别名 tm import test_module as tm # 访问别名模块的 __name__ print(f"别名 tm 对应的模块 __name__:{tm.__name__}") # 输出 test_module # 用别名调用函数(更简洁) result = tm.add(100, 200) print(f"tm.add(100,200) 结果:{result}") # 输出 300 # 当前模块的 __name__ 依然是 __main__ print(f"当前文件的 __name__:{__name__}") # 输出 __main__

运行 main_with_alias.py,输出:

我是 test_module.py,我的 __name__ = test_module 别名 tm 对应的模块 __name__:test_module tm.add(100,200) 结果:300 当前文件的 __name____main__

结论:即使给模块起了别名 tmtm.__name__ 依然是模块的原始文件名(test_module),没有变成别名。

4.2 别名的实际用途

import ... as ... 的核心价值的是「便捷引用」,常见场景:

  1. 简化长模块名:如 import numpy as npimport matplotlib.pyplot as plt(行业通用别名,提升代码可读性);
  2. 避免模块名冲突:若有两个模块同名(如 package1/utils.py 和 package2/utils.py),可通过 import package1.utils as u1import package2.utils as u2 区分。

4.3 补充:原名与别名指向同一模块

如果同时用原名和别名导入同一模块,两者指向同一个模块对象,__name__ 自然完全一致:

import test_module import test_module as tm print(test_module.__name__) # 输出 test_module print(tm.__name__) # 输出 test_module print(test_module is tm) # 输出 True(同一对象)

五、关键注意点与常见误区

注意 1:双下划线不能省略__name__ 是魔法属性,前后各两个下划线,不能写成 _name_name(会变成普通变量,失去内置功能)。
注意 2:包内模块的 __name__:若模块在文件夹(包)中(如 package/test.py),被导入时 __name__ 会是 package.test(包名 + 模块名)。
误区:别名会改变模块属性import ... as ... 仅创建引用别名,不会修改模块本身的任何属性(包括 __name__、函数、类等)。
误区:__name__ 是文件对象的属性__name__ 是「模块」的属性,而非 open() 打开的「文件对象」的属性(文件对象没有 __name__)。

六、总结

Python 的 __name__ 属性是模块的“身份标识”,核心逻辑可概括为:

  • 「直接运行」时,__name__ = "__main__":作为程序入口或测试代码执行;
  • 「被导入」时,__name__ = 模块文件名:用于代码复用;
  • if __name__ == "__main__": 是模块化编程的标准写法,让模块兼具复用性和可测试性;
  • import ... as ... 仅简化引用,不改变模块的 __name__ 及其他属性。

掌握 __name__ 的用法,能让你的 Python 代码更具模块化、可维护性,是从“脚本编程”走向“项目开发”的关键一步。

本文完 | 技术博客仅供学习交流,转载请注明出处