习惯写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__'',所以先把这篇文章发布出来。

def func():
  pass
if __name__ == '__main__':
  pass

Windows系统

不写if __name__ == ''__main__''

报错!

# -*- 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__''

解决了报错的问题

# -*- 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系统下那样报错

# -*- 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

# 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的时候,真的学了好些东西比如多进程(通信),多线程(同步),装饰器,继承,元类等等。

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

posted @ 2020-08-20 21:36  duohappy  阅读(182)  评论(0编辑  收藏  举报