习惯写if __name__ == '__main__'

文章未经允许,不可转载

起初我学习Python的时候,认认真真执行最常规的的写法,把函数调用都写入if __name__ == ‘’__main__‘’。学习导入模块和导入包的时候,知道了写if __name__ == ‘’__main__‘’很重要。一般的教程都会以导入模块或包来说明if __name__ == ‘’__main__‘’的重要性。

这篇文章写点其他的内容来引出if __name__ == ‘’__main__‘’的重要性。

写在前面

本文需要有多进程基础,特别需要了解Linux系统下的fork机制。

在已经发布的爬虫文章中,我都不会加入if __name__ == ‘’__main__‘’,因为好像没啥必要。打算在爬虫系列文章中写多进程时引入if __name__ == ‘’__main__‘’。文章熟悉numpy和pandas中大量使用了if __name__ == ‘’__main__‘’,所以先把这篇文章发布出来。

1
2
3
4
def func():
pass
if __name__ == '__main__':
pass

Windows系统

不写if __name__ == ‘’__main__‘’

报错!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# -*- coding: utf-8 -*-
__author__ = 'duohappy'

import random
from multiprocessing import Process
import os

print('I am ', os.getpid())
rand_num = random.randint(0, 20)

def foo():
print('I am {}, rand_num is {}'.format(os.getpid(), rand_num)) # 子进程的rand_num

print('I am {}, rand_num is {}'.format(os.getpid(), rand_num)) # 父进程的rand_num
p = Process(target=foo)
p.start()
p.join()

'''
不断报错
'''

写if __name__ == ‘’__main__‘’

解决了报错的问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# -*- coding: utf-8 -*-
__author__ = 'duohappy'

import random
from multiprocessing import Process
import os

print('I am ', os.getpid())
rand_num = random.randint(0, 20)

def foo():
print('I am {}, rand_num is {}'.format(os.getpid(), rand_num)) # 子进程的rand_num

if __name__ == "__main__":
print('I am {}, rand_num is {}'.format(os.getpid(), rand_num)) # 父进程的rand_num
p = Process(target=foo)
p.start()
p.join()

'''
I am 16880
I am 16880, rand_num is 10
I am 7592 # 执行了两次print('I am ', os.getpid())
I am 7592, rand_num is 2 # 父进程和子进程的rand_num居然不一样
'''

用fork的思维想了一下
第一:
print(‘I am ‘, os.getpid()),应该只能执行一次啊
第二:
rand_num 应该一样啊

Linux系统

不写if __name__ == ‘’__main__‘’

没有任何问题,不会像Windows系统下那样报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# -*- coding: utf-8 -*-
__author__ = 'duohappy'

import random
from multiprocessing import Process
import os

print('I am ', os.getpid())
rand_num = random.randint(0, 20)

def foo():
print('I am {}, rand_num is {}'.format(os.getpid(), rand_num)) # 子进程的rand_num


print('I am {}, rand_num is {}'.format(os.getpid(), rand_num)) # 父进程的rand_num
p = Process(target=foo)
p.start()
p.join()

'''
I am 3811
I am 3811, rand_num is 17
I am 3841, rand_num is 17
'''
'''
感觉好像靠谱了
'''

使用fork

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# coding : utf-8

import os
import random

print('I am ', os.getpid())
rand_num = random.randint(0, 20)

ret = os.fork()

if ret==0:
print('child pid is {}, rand_num is {}'.format(os.getpid(), rand_num))
else:
print('parent pid is {}, rand_num is {}'.format(os.getpid(), rand_num))

'''
I am 4054
parent pid is 4054, rand_num is 12
child pid is 4084, rand_num is 12
'''
'''
真好
'''

写在后面

本文最先发表在v2ex上,旧文重发。

我有时候写点小需求的时候,能不写if __name__ == ‘’__main__‘’就不写。以前学习Python的时候,真的学了好些东西比如多进程(通信),多线程(同步),装饰器,继承,元类等等。

现在呢,几乎就不写类了,自己的小需求根本就抽象不到这个层次,最有用的还是函数,我可是动不动就给把一段代码封装成一个函数,命一个好名,调用起来嘛,自己的语句就像一句英文句子。

您的支持将鼓励我继续创作!