网站首页 > 技术文章 正文
引言
你了解代码中为什么写 if __ name __ == '__ main __' 吗?它到底是有什么用?
这篇文章除了解释 if __ name __ == '__ main __' ,还将引申一些与 if __ name __ == '__ main __' 相关的知识,例如多进程、单例、模块等等会产生的影响,如果感兴趣就继续往下读吧!
它是什么
if __ name __ == '__ main __' 代表程序的入口。
怎么样,很好理解吧!每一种程序语言都有程序入口:
C语言入口:
#include <stdio.h>
int main()
{
return 0;
}
C++入口
#include <iostream>
int main()
{
return 0;
}
JAVA入口:
public class HelloWorld {
public static void main(String[] args) {
}
}
C#入口:
using System;
namespace HelloWorldApplication
{
class HelloWorld
{
static void Main(string[] args)
{
}
}
}
上面有各种语言的程序入口示例,可以看到除了写法不同,都有一个共同点,那就是使用 main 作为入口名称。
它又不是单纯的程序入口
if __ name __ == '__ main __' 是我们 python 的程序入口,但又不是简单的程序入口。
所以接下来我将深入剖析 if __ name __ == '__ main __' ,来讲解 if __ name __ == '__ main __' 会对哪些产生影响。
原理
如果要讲到影响,我们必须要知道 if __ name __ == '__ main __' 的原理。
我们创建两个模块文件,名为 a.py 与 b.py ,他们的内容如下:
a.py
print(f'a.py {__name__}')
b.py
print(f'b.py {__name__}')
为了两个模块都进行运行,在运行某个模块时,需要引入另一个模块。
运行 a.py 模块
在 a.py 中添加 b.py 模块引入并运行:
import b
print(f'a.py {__name__}')
查看运行结果:
a.py 结果:
a.py __main__
b.py 结果:
b.py b
运行 b.py 模块
在 b.py 中添加 a.py 模块引入并运行:
import a
print(f'b.py {__name__}')
查看运行结果:
a.py 结果:
a.py a
b.py 结果:
b.py __main__
可以看到,当我们运行哪一个模块,相对模块的 __ name __ 将变为 __ main __ ,而其他模块的 __ name __ 就是其本身文件名。
所以当我们运行下面代码:
if __name__ == '__main__':
pass
其实就是当哪一个模块被调用 python xxx.py 时,那个模块文件的 __ name __ 就会变为 __ main __ 。
之后通过判断 if __ name __ == '__ main __' , 即表示被执行模块文件会执行 if 之下的代码;其他模块就算有 if __ name __ == '__ main __' 也不会执行 if 之下的代码。
各种影响
知道了原理,我们就需要来了解 if __ name __ == '__ main __' 对不同场景的影响。
1. 当前模块的影响
之前说过,python 的特性就是模块中的代码都会被执行,因此像下面的代码都会执行:
print('代码执行')
a = 1
b = 3
value = sum([a, b])
print(value)
if __name__ == '__main__':
print('这里是__main__的代码')
执行结果:
代码执行
4
这里是__main__的代码
如何避免影响
为了避免影响,最好的写法是在 if __ name __ == '__ main __' 外尽量少写会被执行的代码,而将需要执行的代码放在 if __ name __ == '__ main __' 下:
def add(a=1, b=3):
value = sum([a, b])
return value
if __name__ == '__main__':
print('代码执行')
sum_value = add(1, 3)
print(sum_value)
print('这里是__main__的代码')
2. 多模块的影响
在单模块的问题,在多个模块中也会存在,因此在多模块时,不要在模块文件中 直接编写可运行代码 ,而是使用 类、函数 进行代替。
除了运行代码影响,还有一个注意的是如果在多个文件中都存在 if __ name __ == '__ main __' ,那么只会执行 python xxx.py 中 xxx.py 的代码,例如下方:
a.py
import b
if __name__ == '__main__':
print('a.py执行')
b.py
if __name__ == '__main__':
print('b.py执行')
当我们执行 a.py 时结果如下:
a.py 结果:
a.py执行
b.py结果:没有任何输出。
如何避免影响
如果必须执行多模块中的方法,可以在其他模块创建一个 函数,然后在运行模块进行调用:
a.py
import b
if __name__ == '__main__':
print('a.py执行')
b.run()
b.py
def run():
print('b.py执行')
3. 多进程的影响
如果你不幸多进程创建在 if __ name __ == '__ main __' 之外,或者使用单例创建了在 __ init __ 中的多进程,那么你可能会得到一个无法结束,不停创建的程序了:
3.1 多进程在判断外
import time
import multiprocessing
def run():
whileTrue:
print(f'子进程')
time.sleep(1)
p = multiprocessing.Process(target=run, args=())
p.start()
if __name__ == '__main__':
print('a.py执行')
3.2 多进程在单例 __ init __
单例 b.py:
import multiprocessing
import time
class B:
_instance = None
_flag = False
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self):
ifnot B._flag:
super().__init__()
self.p = multiprocessing.Process(target=self.run, args=())
self.p.start()
B._flag = True
def run(self):
while True:
print(f'子进程方法')
time.sleep(1)
a.py 调用:
import b
b.B()
if __name__ == '__main__':
print('a.py执行')
如何避免影响
不管是多进程还是多线程,创建执行时需要在 if __ name __ == '__ main __' 之下;单例时,不要在 __ init __ 方法下创建并执行多进程或多线程。
特别说明,如果使用多进程,可以配合
multiprocessing.freeze_support() 来使用,将会省去非常多的麻烦:
if __name__ == '__main__':
multiprocessing.freeze_support()
4. 单例影响
单例影响主要是创建开销。单例如果用来长期运行某些事务而需要开启很多进程或者线程,不要在 __ init __ 中开启,而是另外添加方法开启。这个问题其实跟上面的多进程问题类似。
如何避免影响
创建开启方法,而不是在 __ init __ 中:
单例 b.py:
import multiprocessing
import time
class B:
_instance = None
_flag = False
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self):
ifnot B._flag:
super().__init__()
self.p = None
B._flag = True
def run(self):
while True:
print(f'子进程方法')
time.sleep(1)
def start(self):
ifself.p isNone:
self.p = multiprocessing.Process(target=self.run, args=())
self.p.start()
a.py 调用:
import b
import multiprocessing
if __name__ == '__main__':
multiprocessing.freeze_support()
print('a.py执行')
b.B().start()
结尾
熟练掌握 if __ name __ == '__ main __' 可以让你的程序在运行时避免不必要的开销,特别是在模块、多进程和单例使用时,运用好 if __ name __ == '__ main __' 将会给你省去很多麻烦。
如果这篇文章对你有帮助,点个赞让我知道哦!
猜你喜欢
- 2025-05-26 求职者看过来!最常见的五个面试问题如何答
- 2025-05-26 uboot-main_loop函数分析
- 2025-05-26 太阳的体检表 太阳系漫游①|观天者说
- 2025-05-26 providing/provided ( that)和if作“如果”讲的区别
- 2025-05-26 为什么要写__name__ 是 "__main__"?
- 2025-05-26 条件编译
- 2025-05-26 python学习——035python里if __name__ == "__main__"语句的作用
- 2025-05-26 常用的虚拟语气句型if it wasn't/weren't for用法解析
- 2025-05-26 btrace 开源!基于 Systrace 高性能 Trace 工具
- 2025-05-26 10道C语言笔试模拟题,你能做对几道
- 08-03MySQL数据库的预处理详解
- 08-03《阿常·MySQL 70讲》全套教学视频
- 08-03隐式等待、显示等待和强制等待
- 08-03零基础C#上位机框架项目实例(完结篇)
- 08-03一文搞懂构建Web内容的技术
- 08-03西门子WINCC中的VBScript(VBS)常用于自动化脚本开发
- 08-03力控和sql2000之间的数据转储
- 08-03组态王|通过日历控件选择时间段查询历史报警
- 1521℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 624℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 527℃MySQL service启动脚本浅析(r12笔记第59天)
- 492℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 492℃启用MySQL查询缓存(mysql8.0查询缓存)
- 479℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 461℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 458℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- windowsscripthost (69)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- htmlbackground-image (68)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)