网站首页 > 基础教程 正文
引言
你了解代码中为什么写 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-11 Python——PySide2入门(2) 之 QPushButton
- 2025-05-11 在ubuntu环境下部署svn可视化管理工具iF.SVNAdmin详细教程
- 2025-05-11 了解 Python 中 if __name__ == "__main__" 的作用
- 2025-05-11 python if多条件并列判断的三种方法
- 2025-05-11 「Python条件结构」嵌套if:判断三角形及三角形的类型
- 2025-05-11 SQL用了两年多,分享2个最常用的小技巧
- 2025-05-11 揭秘Python中的魔法语句:if __name__ == '__main__':
- 2025-05-11 测开不得不会的python条件判断语句if
- 2025-05-11 彻底搞懂Python中的if __name__ == '__main__':让你的代码更专业!
- 2025-05-11 python自学者的分享:if-else、for、while语句
- 最近发表
- 标签列表
-
- jsp (69)
- gitpush (78)
- gitreset (66)
- python字典 (67)
- dockercp (63)
- gitclone命令 (63)
- dockersave (62)
- linux命令大全 (65)
- pythonif (86)
- location.href (69)
- dockerexec (65)
- tail-f (79)
- queryselectorall (63)
- location.search (79)
- bootstrap教程 (74)
- deletesql (62)
- linuxgzip (68)
- 字符串连接 (73)
- html标签 (69)
- c++初始化列表 (64)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)