python 程式的使用和理解
概述
一說程式,很多人就想要問執行緒,那麼就先說下兩者的不同吧
其實程式就是一個個的程式
那執行緒其實是程式裡面的一個個子功能
在舉例子來說明,我們以前在電腦前掛QQ,多個qq其實就是一個不同的程式,程式之間是相互獨立執行的,也就是每一個程式都會消耗一份系統的資源。
那麼執行緒呢,就比如說我們點開qq了,看到裡面的各個功能,有什麼聊天,小程式,發空間等等這些,他們就相當於一個個執行緒,也就是說,其實,程式裡面是包含著執行緒的,並且,執行緒是的資源是共享的。
常用方法
我在工作過程中,主要使用的是程式,那能避免使用執行緒,我還是避免使用的,因為資源的共享,會導致出現很多的問題。
那接下來,我就直接說一下程式的簡單使用吧:
首先在python中使用的庫
from multiprocessing import Process,Manager,pool,Value
一般我是這麼匯入,和用到如下的庫。
那麼現在淺顯的說一下上面的幾個函式的使用方法吧
首先Process,就是啟動一個程式,
p = process(引數)
p.start()
其次,Manager,Value的話,主要是多個程式如果使用同一個區域性變數的話,就需要使用上面這兩個函式
Manager有很多的方法,我主要使用dict和list兩種,當然,如果dicct的話,會有一個坑,就是深層複製,無法複製成功,需要由外層進行引導。
最後pool的話是開始一個程式池,這個的話,其實使用方法大致和Process類似。
python multiprocessing
說明幾點:
- 首先,在程式裡面是可以在接著開程式的。
其實程式和執行緒可以搭配著使用,但是這樣就會比較亂。 - 資源共享需要事先宣告,然後不管你開多少個程式,都是共享的,但是,千萬不要再程式裡面再去申明程式。
- 資源共享Manager.dict()是有坑在裡面的,現在接下來就說明這個問題
如果需要對dict的深層賦值,我們只能曾淺層開始一步步傳值。
當時這片文章的一個理解,對我幫助特別大:
https://segmentfault.com/a/1190000018619281
我自己也寫了如下程式碼,淺層次,從使用的角度,驗證了一下:
from multiprocessing import Process,Manager
import datetime
class TestMul(object):
def __init__(self):
self.balck = Manager().dict()
self.freeze = Manager().dict()
self.ips = [
"192.168.111.7",
"192.168.111.8",
"192.168.112.1",
"192.168.112.2",
]
def forall_sleep(fn):
def inloop(self,*args):
for ip in self.ips:
print ip
fn(self,ip,*args)
return inloop
def chose_dict(self):
pass
def decision(self,probelm):
type_anmorl = {
"fullblack": self.balck,
"halfblack": self.freeze,
}
return type_anmorl[probelm]
@forall_sleep
def ip_write1(self,ip,problem):
problem_dict,problem_type = self.decision(problem)
if not problem_dict.has_key(ip):
self.writ_dict2(problem_dict,ip)
print problem_dict
else:
problem_dict["test"]["time"] +=1
print problem_dict
return problem_dict
# 問題的舉例
def writ_dict1(self,dict_massage,ip):
dict_massage[ip] = str(datetime.datetime.now())
dict_massage["test"] = {}
row = dict_massage["test"]
row["time"] = 1
dict_massage["test"] = row
dict_massage["a"] = {}
dict_massage["a"]["b"] = str(datetime.datetime.now())
print dict_massage
def writ_dict2(self,dict_massage,ip):
dict_massage[ip] = str(datetime.datetime.now())
dict_massage["test"] = {}
row = dict_massage["test"]
row["time"] = 1
dict_massage["test"] = row
dict_massage["a"] = {}
raw = dict_massage["a"]
raw["b"] = str(datetime.datetime.now())
dict_massage["a"] = raw
print dict_massage
if __name__ == '__main__':
t = TestMul()
a = t.decision(probelm = "fullblack")
# print a
# t.ip_write1("fullblack") #這個是一般裝飾器的用法
t.writ_dict1(a,"192.168.112.2")
t.writ_dict2(a, "192.168.112.2")
結果如下:
{'test': {'time': 1}, 'a': {}, '192.168.112.2': '2021-01-01 17:18:49.486341'}
{'test': {'time': 1}, 'a': {'b': '2021-01-01 17:18:49.487344'}, '192.168.112.2': '2021-01-01 17:18:49.487202'}
直接看Manager生成的不同的程式碼就可以。
我當時還寫了一個裝飾器,那這裡就額外對裝飾的使用進行一個初步的說明吧。
裝飾器其實就是簡化了我們的一個使用,我上面寫的裝飾器,其實不太正規,但是,可以用來加深對裝飾器的一個理解。
別人的文章會對裝飾器多一個深度的剖析,但是,我們工作中,根本用不到那些東西。只需要把用到的掌握好就可以。
其實裝飾主要是傳引數和不傳引數的,我們主要看最裡面的那層巢狀就好了
def forall_sleep(fn):
def inloop(self,*args):
for ip in self.ips:
print ip
fn(self,ip,*args)
return inloop
首先,說一下*args
一般情況呢,我們還可以帶一個**kwargs
這裡我沒帶,但我都說一下,一個傳入的是不定長的引數,一個字典型的引數,這兩個呢,其實是對應你原函式的一個引數的。
接下來,要關注的是
fn(self,ip,*args)
t.ip_write1("fullblack")
fn其實是代表,原函式的,後面是他要呼叫的引數,這個是要跟原函式一一對應的。
能知道,我為什麼就傳入一個引數了嗎?原函式可以兩個呢?
這也是我為什麼說,我寫的這個裝飾器不正規的原因。因為他不通用。
@forall_sleep
def ip_write1(self,ip,problem):
problem_dict,problem_type = self.decision(problem)
if not problem_dict.has_key(ip):
self.writ_dict2(problem_dict,ip)
print problem_dict
因為這個ip,我放在裝飾器中去了。
關於使用裝飾器,函式是怎麼呼叫的,我推薦大家看我的另一篇文章,當然,也不是我的自賣自誇。
https://blog.csdn.net/weixin_43635231/article/details/110442738
接著說,上面,程式dict的解決辦法,其實就是改成這麼呼叫就可以了
#例子:
def test(idx, test_dict):
test_dict['test'][idx] = idx
## 正確的使用方式
def test(idx, test_dict):
row = test_dict['test']
row[idx] = idx
test_dict['test'] = row
確實有點麻煩,但是卻又是無可奈何
相關文章
- 理解Python asyncio原理和簡潔使用方式Python
- NSProxy的理解和使用
- promise的理解和使用Promise
- 如何理解 python UnicodeEncodeError 和 UnicodeDecodeError :python 的 string 和 unicodePythonUnicodeError
- redis api的使用和理解RedisAPI
- Python技術分享:深入理解ThreadLocal變數的功能和使用Pythonthread變數
- Python中__init__的用法和理解Python
- SpringBoot之ApplicationContextInitializer的理解和使用Spring BootAPPContext
- 使用Python和requests庫的簡單爬蟲程式Python爬蟲
- 深入理解python中的類和物件Python物件
- 簡單理解非同步程式設計(python)和非同步程式設計(nodejs)非同步程式設計PythonNodeJS
- ES6 Promise的使用和理解Promise
- git:rebase(變基)的使用和理解Git
- redis list 使用和理解Redis
- Python中關於++和—(自增和自減)的理解Python
- 程式和執行緒理解執行緒
- Python的安裝和使用Python
- Vue 開發之插槽(slot)的理解和使用Vue
- python使用多程式Python
- 丐版stream流理解和使用
- 白話理解和使用DOCKER VOLUMEDocker
- 透過Python指令碼理解系統程式Python指令碼
- python中zip和format的使用PythonORM
- Python 日誌庫 logging 的理解和實踐經驗Python
- 如何理解Python3中的子類和父類?Python
- 使用 Redis 和 Python 構建一個共享單車的應用程式RedisPython
- Python開發:Python2和Python3的共存和切換使用Python
- 如何優雅的使用和理解執行緒池執行緒
- Vue中keep-alive的深入理解和使用VueKeep-Alive
- 正確理解和使用JAVA中的字串常量池Java字串
- mitmdump+python的使用(程式碼篇)MITPython
- 物件的使用處理,作用域的和ajax中this的理解物件
- Python面試之理解__new__和__init__的區別Python面試
- Python並行程式設計(七):多程式的基本使用和與多執行緒的差異Python並行行程程式設計執行緒
- 如何理解和使用膠囊網路
- 理解並正確使用synchronized和volatilesynchronized
- 使用PyInstaller打包Python程式Python
- 1.5.1 Python程式使用 -- forkPython