代码书写在if __name__ == ‘__main__‘前后的区别

文章讨论了Python代码中if__name__==__main__语句的作用,强调了信号处理函数在主脚本执行时的注册位置,以及其对模块导入的影响。作者建议在理解其原理后在实践中学习。
摘要由CSDN通过智能技术生成

if __name__ == '__main__'这个东西,所有见过python代码的程序猿们一定都不会陌生。为方便理解,有人直接把它等同于java中的主函数。我们今天不是为了来探讨它和Java主函数的异同的(因为我已经忘了Java主函数的细节了,也懒得再回顾…),我们今天就谈一下将代码定义在if __name__ == '__main__'前或者后,到底有什么区别

背景介绍

首先,还是介绍下我为什么又想起这个“python初学者”的问题了。背景是这样的:我有个python脚本,在其中起了一个Flask服务,同时在里面还定义了处理中断信号(SIGINT)的语句,具体你可以认为是这样的:

from flask import Flask
import signal
from b import signal_handler  # 导入b.py中定义的signal_handler函数。至于signal_handler里干了啥,其实就是close了一个数据库连接对象

app = Flask(__name__)

# Flask路由和其他逻辑...

if __name__ == "__main__":
    # 注册信号处理函数
    signal.signal(signal.SIGINT, signal_handler)  # 处理 Ctrl+C
    signal.signal(signal.SIGTERM, signal_handler) # 处理 kill 命令
    
    app.run()

如上所示,这段代码极简单,就是起了个Flask服务,然后在使用Ctrl+C或Kill命令干掉该进程时,先执行signal_handler()函数里面定义的事情(就是关闭了一堆数据库连接)

那么问题来了,signal.signal(signal.SIGINT, signal_handler)这段code,应该定义在if __name__ == "__main__"之前还是之后呢?

问题分析

要想明白这个问题,我们只需搞清if __name__ == "__main__"是干嘛的。

在Python中,if __name__ == "__main__"块确定了代码块是直接作为脚本执行,还是被导入到另一个模块中。当模块被直接执行时,__name__变量被设置为"__main__";当模块被导入时,它通常被设置为模块的名称,也就是说,当脚本被作为模块import时,if __name__ == "__main__"后面的代码不会运行

对于signal.signal(...)的调用,它的位置(在if __name__ == "__main__"之前还是之后)会影响信号处理函数注册的时机和上下文:

  1. 如果signal.signal(...)if __name__ == "__main__"之前定义:
    • 这意味着无论模块是被直接执行还是被导入,信号处理函数都会被注册。这可能不是你想要的行为,因为如果a.py被另一个脚本导入,你可能不希望它改变全局的信号处理设置。
  2. 如果signal.signal(...)if __name__ == "__main__"之后定义:
    • 这意味着只有当当前作为主脚本直接运行时,信号处理函数才会被注册。这通常是更安全和更可控的做法,因为它避免了意外地改变导入此模块的其他脚本的信号处理行为。

问题解决

所以说,我们前面的定义位置是正确的。因为只有当直接运行该脚本时,才会执行到app.run(),才会运行Flask服务、才需要在接受到Kill信号时进行处理、才需要让signal.signal(...)定义生效。所以,signal.signal(...)app.run()可以说是同时存在的,那么这两行代码就应该一起放在if __name__ == '__main__'之后

emmm,有时候没遇到一定的场景,确实很难切身体会到一些相对少见用法的意义。比如 __name__的取值,这个相信所有写python的朋友在初学时都看到过对它的解释,但真正在用到它的时候,才会让你理解它存在的意义。所以,最好的学习方式,我猜,就是在实践中学习,而在此之前,首先应该有一个爱刨根问底的精神。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_illusion_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值