sys&faker&jsonpath模塊、異常處理、多線程、多進程
1.sys模塊
sys.argv 能獲取運行文件時,文件名后面所傳參數(shù)。結(jié)果是一個列表。
import sys print(sys.argv) #獲取運行python文件的時候傳入的參數(shù),會連同文件名,和參數(shù),返回一個列表。 #在terminal里運行,才能傳參。如在當(dāng)前目錄下,運行 python sys模塊.py arg1 if len(sys.argv)>1: if sys.argv[1]=='--help': quit('這個python是用來測試的,運行的時候需要使用 python a.py port') else: port = sys.argv[1] else: port = 7878 import flask server = flask.Flask(__name__) @server.route('/') def index(): return '<h1>首頁</h1>' server.run(port=port)
運行上邊代碼,返回:

2.faker模塊
import faker f = faker.Faker(locale='zh_CN') #實例化,并指定語言為中文 print(f.name())#姓名 print(f.credit_card_number())#隨機信用卡號 print(f.email())#隨機信用卡號 print(f.ipv4())#隨機ip地址 print(f.user_name())#隨機用戶名 print(f.phone_number())#隨機電話 print(f.ssn())#隨機身份證號
3.jsonpath模塊
d={ "error_code": 0, "stu_info": [ { "id": 2059, "name": "小白", "sex": "男", "age": 28, "addr": "河南省濟源市北海大道32號", "grade": "天蝎座", "phone": "18378309272", "gold": 10896, "info":{ "card":6214234235232352, "bank_name":'中國銀行', "name":'zff' } } ], 'name':'哈哈哈' } #普通取name res = d['stu_info'][1]['name'] print(res) # jsonpath取name import jsonpath res = jsonpath.jsonpath(d,'$..name') #模糊匹配,不管層次與位置.$代表外部大字典,..代表任意的。。 #res2 = d['stu_info'][0]['info']['bank_name'] #res2=jsonpath.jsonpath(d,'$.['stu_info'][0]['info']['bank_name']') #這2個res2效果是一樣的
4.面向?qū)ο蟆^承
在父類某個方法的基礎(chǔ)上再增加新功能:
super().xxx()
super()會自動找到父類
class Car: def run(self,): print('running...') return 'abc' class NewCar(Car): def run(self): res = super().run()# 保留父類run的方法,super()的意思就是找到父類 #res=Car().run() #與上邊super功能一樣,但父類名稱改的時候,他也得改 print('fly...',res) bmw = NewCar() bmw.run()
5.異常處理
處理異常,將出錯的情況進行處理,使出錯時拋出提示或要求繼續(xù)某種操作,而不是報錯讓程序進行不下去。
用 try: xxx except Exception as e: print('提示語')
try和except是必須的,else和finally選用。
try: res = 1 / 0 except ZeroDivisionError as e: #except ZeroDivisionError,e: #python2不能用as,要用, print('出錯啦,除數(shù)不能為0',e) l = list() l.append(1) d = dict() # d['name']='abc' try: print(d['name']) print(l[-1]) except IndexError as e: #只能捕捉到越界下標(biāo)錯誤 print('出錯了,下標(biāo)越界',e) except KeyError as e: print('字典key不存在',e) except Exception as e: #能捕捉各種異常,但不會界定是何種異常 print('未知異常',e) else: print('沒有出現(xiàn)異常。。。') finally: #不管異常是否出現(xiàn),都會執(zhí)行,使用場景:打開文件或數(shù)據(jù)庫,出錯了,但也得關(guān)閉 print('什么時候執(zhí)行finally') dic = {} print(dic['name']) class NumberError(Exception): pass class M: def main(self): count = input('請輸入要產(chǎn)生多條銀行卡號:').strip() if not count.isdigit(): raise NumberError('輸入的數(shù)字不對') #主動拋出異常,判斷為一個什么時候,終止運行 #raise Exception('自定義異常') m = M() m.main()
6.多線程
線程:程序執(zhí)行的最小單位。
為什么有時候單線程比主線程快?
電腦CPU有幾個核心,就同時只能運行幾個線程。
感覺多線程運行。很快,其實并沒有,只是CPU運行速度特別快,切換速度特別快
全局解釋器鎖,叫GIL。python加了個鎖,讓每個CPU只運行一個線程,避免數(shù)據(jù)錯亂。
單線程:沒有做多線程,就是單線程
多線程:利用for語句,啟動多個線程
for i in range(20): #啟動了多個線程
t1 = Thread(target=run,)
t1.start()
主線程等待子線程執(zhí)行任務(wù):t.join()
或
while threading.active_count()!=1: #判斷子線程是否執(zhí)行結(jié)束,這種簡單
pass
#運行程序規(guī)則:首先由一個線程,會將代碼從頭到尾執(zhí)行一遍。 import threading #該模塊提供線程 from threading import Thread import time def run(): time.sleep(1) print('run...') start_time = time.time() # for i in range(5): #串行,得5s,單線程運行 run() threads = [] for i in range(20): #啟動了多個線程 t1 = Thread(target=run,) t1.start() #t1.join() #這兒不能加,否則會變成串聯(lián)線程,即單線程 # threads.append(t1) # for t in threads: #循環(huán),同時等待多個線程 # t.join() #這一部分是一個等待代碼 while threading.active_count()!=1: #判斷子線程是否執(zhí)行結(jié)束,這種比上邊等待代碼塊簡單 pass end_time = time.time() print(end_time - start_time)
7.多進程
用法上跟多線程特別相似
進程:
一些資源的集合。如qq, 圖片,程序
一個進程里面最少有一個線程, 主線程。
一個進程可以包含多個線程
可以利用多個cpu的。
IO密集型任務(wù): 即input output,分為磁盤io和網(wǎng)絡(luò)io
IO消耗比較多的,適合多線程
CPU密集型任務(wù):消耗CPU多的,適合多進程
為啥python的多線程利用不了多核CPU,但是咱們看起來的時候還是并發(fā)的?
因為在Python多線程下,每個線程的執(zhí)行方式:
1、獲取GIL
2、執(zhí)行代碼直到sleep或者是python虛擬機將其掛起。
3、釋放GIL
可見,某個線程想要執(zhí)行,必須先拿到GIL,我們可以把GIL看作是“通行證”,
并且在一個python進程中,GIL只有一個。拿不到通行證的線程,就不允許進入CPU執(zhí)行。
import multiprocessing import time import threading import requests def run(): time.sleep(10) print('run...') if __name__ == '__main__': for i in range(10): p = multiprocessing.Process(target=run) p.start() while multiprocessing.active_children(): #等待其他子進程運行結(jié)束 pass
8.守護線程
守護主線程,主線程執(zhí)行完成之后,子線程立即結(jié)束。如秦始皇死,相關(guān)人都得死。
import threading import time def run(): time.sleep(5) print('run。。。') for i in range(100): puren = threading.Thread(target=run) puren.setDaemon(True)#設(shè)置子線程為守護線程。如果不加,這個會運行100次run.加了后,運行一次。 puren.start() print('over') #即不加等待,主線程一運行完,子線程就停止運行。
9.鎖
多個線程同時去操作同一個數(shù)據(jù)的時候,可能會導(dǎo)致數(shù)據(jù)不正確。
要把這個數(shù)據(jù)機上鎖,這樣同時就只能有一個線程在操作這個數(shù)據(jù)了。
python3會自動加鎖,所有寫不寫加不加鎖代碼沒所謂
import threading count = 0 lock = threading.Lock() #申請一把鎖 def run(): global count with lock: count+=1 # lock.acquire()#加上鎖 # count+=1 # lock.release()#釋放,必須的,要么會停著不動 #這3行代碼跟上邊功能一樣 #python里邊不加鎖也行,因為python3會自動加鎖 for i in range(10): #多個線程都要去操作count數(shù)據(jù) t = threading.Thread(target=run) t.start() while threading.active_count()!=1: pass print(count)
10.牛刀小試
生成尾號為11的銀行卡號:

# 10 #工商銀行:6222342 #廣發(fā)銀行:34634 #1、獲取數(shù)據(jù),把不需要的數(shù)據(jù)過濾掉 import random import string class BankCardId: file_name = 'card_no' all = [] # 保存所有有效的數(shù)據(jù) def __init__(self):#自動調(diào)用函數(shù),取到all self.get_data() def get_data(self): #取到最后倆位數(shù)為11的數(shù)據(jù),all取到[['工商銀行', '18', '620200'], ['工商銀行', '18', '620302'],...] with open(self.file_name,encoding='utf-8') as fr: for line in fr: if line.strip():#判斷不是空行 new_line = line.split()[1:] a,b = new_line[-1],new_line[-2] #獲取末尾2個元素 if a==b=='1':#判斷末尾2個元素是不是都是1 self.all.append(new_line[:3]) def get_card(self): #生成銀行卡號 bank_name,lenth,start = random.choice(self.all) other_lenth = int(lenth) - len(start) - 2 other = ''.join( random.choice(string.digits) for i in range(other_lenth) ) res = start + other + '11' print(bank_name,self.my_print(res)) def my_print(self,s): count = 0 new_s = '' for i in s: count += 1 new_s += i if count == 4: new_s += ' ' count = 0 return new_s def main(self): num = input('請輸入要產(chǎn)生多少條:').strip() for i in range(int(num)): self.get_card() b = BankCardId() # b.get_data() # print(b.all) b.main()
下載網(wǎng)頁圖片:
import threading import requests import random import time from hashlib import md5 res = [] def down_load_pic(url): #下載圖片的url r = requests.get(url) file_name = md5(r.content).hexdigest()#把文件md5之后字符串當(dāng)做文件名 with open(file_name+'.jpg','wb') as fw: fw.write(r.content) print('%s下載完成'%file_name) res.append(file_name) urls = [ 'http://www.nnzhp.cn/wp-content/uploads/2018/12/110405th7jtus7gjjlywnl.jpg', 'http://www.nnzhp.cn/wp-content/themes/QQ/images/thumbnail.png', 'http://www.nnzhp.cn/wp-content/uploads/2018/08/f38a12137574f4333f7686f7e75a06fb8bd9fed537ea59-pRwNuK_fw658.jpeg', 'http://www.nnzhp.cn/wp-content/uploads/2018/08/c1bba9a47cfe8fe7000f137f020ad623.png', ] start_time = time.time() #單線程 # for url in urls: # down_load_pic(url) #多線程 for url in urls: t = threading.Thread(target=down_load_pic,args=(url,) ) t.start() while threading.active_count()!=1:#等待子線程運行完成 pass print(res) end_time = time.time() print('下載完成,下載時間是 %s'% (end_time-start_time)) # 下載完成,下載時間是 107.56531095504761,單線程 # 下載完成,下載時間是 81.53419184684753 多線程

浙公網(wǎng)安備 33010602011771號