网易首页 > 网易号 > 正文 申请入驻

深入剖析Python基础:揭开__name__与__main__的神秘面纱

0
分享至

今天分享的是if __name__ == '__main__':详细解释#python#

基本概念

if __name__ == '__main__': 是Python中一个非常重要的惯用法,用于判断当前模块是作为主程序运行,还是被导入到其他模块中。

详细解释

__name__变量

  • __name__ 是Python的一个内置变量
  • 当一个模块被直接运行时,__name__ 的值为 '__main__'
  • 当一个模块被导入到其他模块中时,__name__ 的值为模块本身的名称

条件判断的作用

if __name__ == '__main__':# 这里的代码只有在直接运行这个文件时才会执行# 当这个文件被导入时,这里的代码不会执行
实际示例示例1:基础用法

# example1.pydef greet(name):"""一个简单的问候函数"""return f"Hello, {name}!"def main():"""主函数"""print("这个文件被直接运行了!")print(greet("Alice"))print(greet("Bob"))# 只有在直接运行这个文件时才会执行main()函数if __name__ == '__main__':main()print(f"模块名称: {__name__}")

运行结果(直接运行 example1.py):

这个文件被直接运行了!Hello, Alice!Hello, Bob!模块名称: __main__

运行结果(在其他文件中导入 example1.py):

# another_file.pyimport example1print("在另一个文件中导入example1")print(example1.greet("Charlie"))输出:模块名称: example1在另一个文件中导入example1Hello, Charlie!
示例2:模块测试

# math_utils.pydef add(a, b):"""加法函数"""return a + bdef multiply(a, b):"""乘法函数"""return a * bdef subtract(a, b):"""减法函数"""return a - b# 测试代码if __name__ == '__main__':# 这些测试只有在直接运行这个文件时才会执行print("=== 运行数学工具测试 ===")print(f"add(5, 3) = {add(5, 3)}")           # 应该输出 8print(f"multiply(4, 6) = {multiply(4, 6)}") # 应该输出 24print(f"subtract(10, 7) = {subtract(10, 7)}") # 应该输出 3print("=== 测试完成 ===")

作为模块导入时:

# main_program.pyimport math_utils# 使用math_utils模块中的函数result = math_utils.add(10, 20)print(f"10 + 20 = {result}")  # 输出: 10 + 20 = 30# 不会执行math_utils.py中的测试代码
示例3:配置不同的行为

# config_manager.pyclass ConfigManager:def __init__(self):self.settings = {}def load_config(self, config_file):"""加载配置文件"""# 模拟加载配置self.settings = {"debug": True, "port": 8080}print(f"配置已从 {config_file} 加载")def get_setting(self, key):"""获取配置项"""return self.settings.get(key)# 根据运行方式提供不同的行为if __name__ == '__main__':# 直接运行时:提供测试和演示功能print("=== 配置管理器演示模式 ===")manager = ConfigManager()manager.load_config("demo_config.json")print(f"Debug模式: {manager.get_setting('debug')}")print(f"端口号: {manager.get_setting('port')}")else:# 被导入时:提供生产环境配置print("=== 配置管理器生产模式 ===")manager = ConfigManager()manager.load_config("production_config.json")
示例4:复杂的应用程序结构

# app_main.pydef setup_database():"""设置数据库连接"""print("初始化数据库连接...")return "database_connection"def load_config():"""加载应用配置"""print("加载应用配置...")return {"host": "localhost", "port": 8000}def start_server(host, port):"""启动服务器"""print(f"服务器启动在 {host}:{port}")def main():"""应用程序主入口"""print("=== 应用程序启动 ===")# 初始化组件db_conn = setup_database()config = load_config()# 启动服务start_server(config["host"], config["port"])print("=== 应用程序运行中 ===")# 单元测试函数def test_components():"""测试各个组件"""print("=== 运行组件测试 ===")config = load_config()assert config["host"] == "localhost"assert config["port"] == 8000print("所有测试通过!")if __name__ == '__main__':import sys# 支持命令行参数if len(sys.argv) > 1 and sys.argv[1] == "test":# 如果传入test参数,运行测试test_components()else:# 否则运行主程序main()

运行方式:

# 正常运行应用python app_main.py# 输出:# === 应用程序启动 ===# 初始化数据库连接...# 加载应用配置...# 服务器启动在 localhost:8000# === 应用程序运行中 ===# 运行测试python app_main.py test# 输出:# === 运行组件测试 ===# 加载应用配置...# 所有测试通过!
示例5:在包结构中的使用

my_package/├── __init__.py├── module_a.py└── module_b.py

# my_package/module_a.pydef function_a():return "这是模块A的功能"if __name__ == '__main__':# 直接测试这个模块print("测试模块A:")print(function_a())

# my_package/module_b.pydef function_b():return "这是模块B的功能"if __name__ == '__main__':# 直接测试这个模块print("测试模块B:")print(function_b())

# my_package/module_b.pydef function_b():return "这是模块B的功能"if __name__ == '__main__':# 直接测试这个模块print("测试模块B:")print(function_b())
在自动化测试框架中的应用示例6:测试框架中的使用

# test_runner.pyimport pytestimport sysfrom common.test_case_collector import get_caseinfodef run_all_tests():"""运行所有测试"""print("启动测试框架...")# 获取所有测试用例test_cases = get_caseinfo()print(f"找到 {len(test_cases)} 个测试用例")# 运行pytestpytest_args = ["-v","--html=report.html","--self-contained-html"exit_code = pytest.main(pytest_args)return exit_codedef run_specific_test(test_name):"""运行特定测试"""print(f"运行特定测试: {test_name}")pytest_args = ["-v",f"-k {test_name}","--html=report.html"return pytest.main(pytest_args)if __name__ == '__main__':import argparse# 创建命令行解析器parser = argparse.ArgumentParser(description='测试框架运行器')parser.add_argument('--test', help='运行特定测试')parser.add_argument('--list', action='store_true', help='列出所有测试用例')args = parser.parse_args()if args.list:# 列出测试用例test_cases = get_caseinfo()for i, case in enumerate(test_cases, 1):print(f"{i}. {case.get('name', '未命名用例')}")elif args.test:# 运行特定测试exit_code = run_specific_test(args.test)sys.exit(exit_code)else:# 运行所有测试exit_code = run_all_tests()sys.exit(exit_code)
主要作用总结

1.模块测试

if __name__ == '__main__':# 放置测试代码test_function1()test_function2()

2.脚本入口点

if __name__ == '__main__':# 作为脚本运行时的主逻辑main()

3.防止导入时执行

# 这些代码在导入时不会执行if __name__ == '__main__':init_database()  # 重量级操作,不应该在导入时执行start_server()   # 阻塞操作,不应该在导入时执行

4.提供不同的行为

if __name__ == '__main__':# 直接运行时:演示或测试模式run_demo()else:# 被导入时:生产模式setup_production()

5.命令行工具

if __name__ == '__main__':import argparse# 解析命令行参数# 提供不同的功能选项
最佳实践

1将主要逻辑放在函数中

def main():# 主要逻辑passif __name__ == '__main__':main()

2使用命令行参数

if __name__ == '__main__':import sysif len(sys.argv) > 1:# 处理参数pass

3提供有用的错误信息

if __name__ == '__main__':try:main()except Exception as e:print(f"错误: {e}")sys.exit(1)
总结

if __name__ == '__main__': 是Python编程中非常重要的一个习惯用法,它使得:

  • 模块可以自包含测试代码
  • 避免导入时执行不必要的代码
  • 提供灵活的脚本行为
  • 支持模块的多种使用方式

这个结构让Python模块既可以作为可重用的库,也可以作为独立的脚本运行,大大提高了代码的灵活性和可维护性。



特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
有一半华人血统,泰国王后“回娘家”

有一半华人血统,泰国王后“回娘家”

亚太观澜
2025-11-12 21:00:05
太阳报:C罗日收入48.8万英镑,与摩根采访时戴的手表值110万英镑

太阳报:C罗日收入48.8万英镑,与摩根采访时戴的手表值110万英镑

懂球帝
2025-11-12 23:09:09
尹锡悦的“保护伞”,终于被揪了出来,手里的重要证据已被销毁?

尹锡悦的“保护伞”,终于被揪了出来,手里的重要证据已被销毁?

南宫一二
2025-11-13 17:05:52
湖南省郴州市委原常委、统战部原部长黄峥嵘被决定逮捕,曾被通报跑官买官、私德不修

湖南省郴州市委原常委、统战部原部长黄峥嵘被决定逮捕,曾被通报跑官买官、私德不修

鲁中晨报
2025-11-13 16:19:01
超700台光刻机!荷兰ASML公司可能要全部回购?外媒:事情闹大了

超700台光刻机!荷兰ASML公司可能要全部回购?外媒:事情闹大了

大卫聊科技
2025-11-13 13:44:04
茼蒿立大功!医生调查发现:茼蒿对这5种疾病有好处,建议常吃

茼蒿立大功!医生调查发现:茼蒿对这5种疾病有好处,建议常吃

阿纂看事
2025-10-13 15:36:03
各有目的!全红婵家别墅正式封顶,令人不适的事发生,还不止一件

各有目的!全红婵家别墅正式封顶,令人不适的事发生,还不止一件

春序娱乐
2025-11-13 18:26:15
45岁依然拍三级片寻求刺激?从亿万富豪到烂片女王,她在追求什么

45岁依然拍三级片寻求刺激?从亿万富豪到烂片女王,她在追求什么

牛牛叨史
2025-11-05 14:10:58
两岸同谋统一,美国开始介入了,郑丽文赶赴大陆前,先被美方约谈

两岸同谋统一,美国开始介入了,郑丽文赶赴大陆前,先被美方约谈

Ck的蜜糖
2025-11-14 00:31:48
我住养老院 儿子10年没来看我,直到他公司破产,才想起他还有个妈

我住养老院 儿子10年没来看我,直到他公司破产,才想起他还有个妈

今日美食分享
2025-11-13 00:44:34
2025河南百强企业揭晓:首次出现2000亿巨头,胖东来入榜,民企胜出国企

2025河南百强企业揭晓:首次出现2000亿巨头,胖东来入榜,民企胜出国企

双色球的方向舵
2025-11-13 13:41:51
银行卡内存款“莫名”变基金?农行、支付宝回应

银行卡内存款“莫名”变基金?农行、支付宝回应

中国能源网
2025-11-13 12:13:06
狗咬邻居被摔死后主人上门打砸遭反杀,邻居以故意伤害罪被公诉,案件一审将开庭

狗咬邻居被摔死后主人上门打砸遭反杀,邻居以故意伤害罪被公诉,案件一审将开庭

扬子晚报
2025-11-12 19:59:31
河南开封万岁山景区网红NPC“蓝狐狸”再被辞退

河南开封万岁山景区网红NPC“蓝狐狸”再被辞退

界面新闻
2025-11-12 16:08:06
iPhone 18 Pro Max:一部趋近250克的“重量级”手机?

iPhone 18 Pro Max:一部趋近250克的“重量级”手机?

小柱解说游戏
2025-11-14 00:58:14
“狗咬人引发命案”:死者妹妹说:我们才是受害者,网友不分黑白

“狗咬人引发命案”:死者妹妹说:我们才是受害者,网友不分黑白

汉史趣闻
2025-11-13 10:10:57
英媒:红军城万名乌克兰伤兵患气性坏疽

英媒:红军城万名乌克兰伤兵患气性坏疽

凤凰卫视
2025-11-13 11:26:28
日本可能与中国开战?日专家:与中国发生冲突,最长只能坚持两周

日本可能与中国开战?日专家:与中国发生冲突,最长只能坚持两周

历史求知所
2025-11-04 10:15:03
仅剩2000多万人?比乌克兰投降更可怕的事情是,再打可能亡国了

仅剩2000多万人?比乌克兰投降更可怕的事情是,再打可能亡国了

历史求知所
2025-11-11 07:05:03
就在今天!11月13日晚上,NBA传来詹姆斯、拉文、东契奇新消息!

就在今天!11月13日晚上,NBA传来詹姆斯、拉文、东契奇新消息!

山河入画屏
2025-11-14 01:08:25
2025-11-14 03:51:00
娱乐督察中
娱乐督察中
独乐乐不如众乐乐
170文章数 20027关注度
往期回顾 全部

科技要闻

月产能突破百万片,中芯国际Q3净利增43.1%

头条要闻

高市早苗扯着眼皮诉苦:我现在每天只睡2小时

头条要闻

高市早苗扯着眼皮诉苦:我现在每天只睡2小时

体育要闻

跟豪门传了十年绯闻,他却偏要“择一队终老”

娱乐要闻

王鹤棣孟子义真要搭?

财经要闻

源峰25亿赌局!汉堡王中国"卖身"求生

汽车要闻

具备高阶辅助驾驶功能 欧拉5预售价10.98万起

态度原创

艺术
数码
家居
本地
公开课

艺术要闻

春风拂面!古典美与工笔画的绝妙碰撞。

数码要闻

英特尔 XeSS SDK 升级至 2.1.1 版本,Meteor Lake 也能用帧生成

家居要闻

莫奈时间 重构先锋概念

本地新闻

云游安徽 | 江声浩荡阅千年,文脉相承看芜湖

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版