python sys.exit 退出 多进程 多线程_Python自动化学习笔记(十)——多进程,多线程,异常处理,faker模块,sys模块,jsonpath模块...

本文介绍了Python中的多线程和多进程,包括如何创建和启动线程,多线程下载图片,线程锁的使用,守护线程的概念。同时,讲解了多进程的实现和异常处理,如try-except结构,自定义异常。还提到了sys.argv参数获取和faker模块用于生成模拟数据的功能,以及jsonpath模块在处理JSON数据时的作用。
摘要由CSDN通过智能技术生成

1.多线程

1.1多线程创建和启动

进程:一些资源的集合

线程:程序执行的最小单位

线程包含在进程内,进程是由若干线程组成的,一个进程至少有一个线程。

多任务可以由多进程完成,也可以由一个进程内的多线程完成。

启动一个线程就是把一个函数传入并创建Thread实例,然后调用start()开始执行,循环创建线程时,应当全部创建完毕后,再循环每一个线程执行t.join,否则和串行效率就一样了,代码示例:

importthreadingimporttimedefrun():

time.sleep(1)print('run.............')

starttime=time.time()

threads=[]for i in range(20):#循环创建20个线程

t1=threading.Thread(target=run,) #实例化一个线程

threads.append(t1)

t1.start()#启动线程#for t in threads:#循环每一个线程并t.join来等待#t.join() #主线程等待子线程执行结束

while threading.active_count()!=1:passendtime=time.time()print(endtime-starttime)

一个多线程下载图片的例子如下

两个知识点:

多线程运行时拿不到函数的返回值,可以定义一个全局变量,把返回值存储到全局变量中

实例化线程时,函数运行的参数可以通过一个list传入,t=threading.Thread(target=download_pic,args=(url,))

importrequestsfrom hashlib importmd5importthreadingimporttime

filename=[]defdownload_pic(url):

r=requests.get(url)

file_name=md5(r.content).hexdigest() #文件内容md5后的字符串拿来当作文件名

with open(file_name+'.jpg','wb')as fw:

fw.write(r.content)

filename.append(file_name)#多线程运行时拿不到函数的返回值,可以定义一个全局变量,把返回值存储到全局变量中

urls=['https://cn.bing.com/az/hprichbg/rb/GoldenEagle_ZH-CN2823955379_1920x1080.jpg','https://cn.bing.com/az/hprichbg/rb/GoldenEagle_ZH-CN2823955379_1920x1080.jpg','https://cn.bing.com/az/hprichbg/rb/NapoleonsHat_ZH-CN2968205603_1920x1080.jpg','https://cn.bing.com/az/hprichbg/rb/Snowkiters_ZH-CN3098762517_1920x1080.jpg']

start_time=time.time()#单线程下载#for url in urls:#download_pic(url)#多线程下载

for url inurls:

t=threading.Thread(target=download_pic,args=(url,))

t.start()while threading.active_count()!=1:passend_time=time.time()print('下载完成,下载时间为%s'%(end_time-start_time))print('下载图片文件名称分别为:',filename)

2.2 锁

确保一个线程在修改一个参数时,别的线程一定不能改,我们可以给这个参数加一把锁,修改完毕后再释放锁

importthreading

count=0

lock=threading.Lock() #申请一把锁,多个线程操作同一个数据时,要加锁

defrun():globalcount

with lock:#加锁,python3会自动加锁

count+=1

for i in range(10):

t=threading.Thread(target=run,)

t.start()while threading.active_count()!=1:pass

print(count)

不写with lock的话,加锁和释放锁的方法分别是:lock.acquire()和lock.release()

2.3守护线程

#守护线程:守护主线程,主线程执行完成后子线程立即结束

importthreadingimporttimedefrun():

time.sleep(5)print('run...')for i in range(100):

puren=threading.Thread(target=run)

puren.setDaemon(True)#设置子线程为守护线程

puren.start()print('over')

输出如下,子线程的run方法还没有执行就结束了,因为主线程结束了,所以守护线程立即结束

2.多进程

在Python中,多个线程也只能利用一个cpu核心,如果想要实现多核任务,把每个cpu核心都利用起来,只能使用多进程来实现。通常我们可以利用多线程来执行IO密集型任务,多进程来执行CPU密集型任务

下面的例子演示了循环启动多个子进程并等待其结束:

importmultiprocessingimporttimedefrun():

time.sleep(2)print('run...')if __name__ == '__main__':for i in range(10):

p=multiprocessing.Process(target=run) #实例化一个进程

p.start() #启动一个进程

while multiprocessing.active_children():#等待其他子进程运行完毕

pass

多进程传入调用函数参数的方法和多线程的一致,p=multiprocessing.Process(target=run,args=(url,))

3.异常处理

3.1 try-except

语法示例如下:

d={}

l=[]try:print(d['name'])print(l[-1])except KeyError as e: #多个异常,多个except

print('字典里没有这个key',e)exceptIndexError as e:print('出错了,下标越界',e)except Exception as e: #捕捉所有异常

print('出现异常了',e)else: #没有出现异常时

print('没有异常')finally:print('finally')

ps:finally里的语句一定会执行

3.2 自定义异常

class NumberError(Exception): #定义一个异常类,继承Exception

pass

classM:defMain(self):

count=input('请输入要产生多少条银行卡号')if notcount.isdigit():raise NumberError #抛出一个异常

for i inrange(int(count)):

self.card()

m=M()

m.Main()

输出为:

4.sys.argv

通过sys模块下的argv属性,可以获取运行python文件的时候传入的参数,代码示例:

importsysprint(sys.argv) #获取运行python文件的时候传入的参数

if len(sys.argv)>1:if sys.argv[1]=='--help':

quit('这个python是用来测试的,运行的时候需要使用python a.py port')else:

port=sys.argv[1]else:

port=7878

importflask

server= flask.Flask(__name__)

@server.route('/')defindex():return '

首页

'server.run(port=port)

以上代码,如果运行Python文件时输入:python sys模块.py 8888,则启动接口的端口为8888,如下图所示,不添加参数,默认启动,则端口为7878,传入多个参数时,用空格隔开

在pycharm运行代码时,在下图位置设置参数,再运行,也可以将参数传入

5.faker模块

faker模块是一个很强大的外部模块,可以生成各种数据,例如身份证号,电话号码,人名,地址等。示例:

from faker importFaker

f=Faker(locale='zh_CN') #实例化

print(f.name()) #人名

print(f.postcode())#邮编

print(f.credit_card_number()) #身份证号

print(f.ssn())#身份证号

print(f.ipv4()) #ip地址

print(f.password()) #密码

print(f.address()) #地址

print(f.user_name()) #用户名

6.jsonpath

利用jsonpath模块可以快速找到json字典里的key,字典内有多重嵌套时非常好用,示例如下:

d={"error_code": 0,"stu_info": [

{"id": 2059,"name": "小白","sex": "男","age": 28,"addr": "河南省济源市北海大道32号","grade": "天蝎座","phone": "18378309272","gold": 10896,"info":{"card":23333,"bank_name":"中国银行"}

},

{"id": 2067,"name": "小名","sex": "男","age": 28,"addr": "河南省济源市北海大道32号","grade": "天蝎座","phone": "12345678915","gold": 100},

{"id": 2086,"name": "小红","sex": "男","age": 28,"addr": "河南省济源市北海大道32号","grade": "狮子座","phone": "15837627044","gold": 4040},

{"id": 2095,"name": "小懒","sex": "男","age": 24,"addr": "河南省项城市秣陵镇","grade": "摩羯座","phone": "13608417301","gold": 100},

{"id": 2107,"name": "小黑","sex": "女","age": 10,"addr": "河南省康定大道158号","grade": "水瓶座","phone": "17612227885","gold": 700},

{"id": 2142,"name": "小允","sex": "男","age": 24,"addr": "河南省项城市秣陵镇","grade": "摩羯座","phone": "13608417304","gold": 100},

{"id": 2240,"name": "小黄","sex": "男","age": 28,"addr": "深圳市南山区","grade": "天蝎座","phone": "12456785512","gold": 100}

]

}importjsonpath

res=jsonpath.jsonpath(d,'$.stu_info[0].info.bank_name')print(res)

res=jsonpath.jsonpath(d,'$..bank_name') #查找内部key,存在的话返回key的value,不存在返回false

print(res)

res=jsonpath.jsonpath(d,'$..error_code') #查找内部key,存在的话返回key的value,不存在返回false

print(res)

res=jsonpath.jsonpath(d,'$..bakkk') #查找内部key,存在的话返回key的value,不存在返回false

print(res)

输出结果为:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值