snmpset对象不可写_[Python]可变对象与多进程通信
一、可變對象與不可變對象
參考Python 的函數是怎么傳遞參數的?
具體看文檔就行了,這里引用文章的結論:
1.對于不可變對象作為函數參數,相當于C系語言的值傳遞;2.對于可變對象作為函數參數,相當于C系語言的引用傳遞;
另外有評論指出,Python中的函數通過引用傳參,只不過對于不可變對象,會創建新的對象,并將原來的變量名綁定到新的對象上。
另外有一個哥們喋喋不休在評論這么一段代碼:
ls = [1,2,3]def test(list):······ list = []test(ls)print(ls)說實話我也很懵逼,為什么沒有改變?后來發現還是這哥們對Python不熟悉啊,如果對命名空間了解多一點就不會問這個了,我可以寫這一段代碼:
def test1(listA):print ("id(listA) = %s" % id(listA))listA.append(4)listA = []print ("id(listA) = %s" % id(listA))def test():ls = [1, 2, 3]print ("id(ls) = %s" % id(ls))test1(ls)print ("After test1, ls = %s" % ls)輸出的結果是:
id(ls) = 140407795100040 id(listA) = 140407795100040 id(listA) = 140407795131528 After test1, ls = [1, 2, 3, 4]可見用內置方法還是可以改變的,listA這個變量開始是綁定到id為140407795100040即與ls相同的內存上,這種情況是可以用內置方法進行操作的,如果重新賦值成空列表相當于把變量listA綁定到另一塊內存上。
ps.如果想清空該列表可以用內置方法clear(),以下為實驗過程:
def test2(listA):listA.clear()print ("id(listA) = %s" % id(listA))def test():ls = [1, 2, 3]print ("id(ls) = %s" % id(ls))test2(ls)print ("After test1, ls = %s" % ls)輸出的結果是:
id(ls) = 140632970701192 id(listA) = 140632970701192 After test1, ls = []一篇寫的不錯的文章:Python的函數參數傳遞:傳值?引用?
我的結論:傳參傳的都是變量名,如果在函數體內能改變變量名指向的對象,那么該變量名指向的是可變對象,如果改變不了,那么指向的是不可變對象。
最后純記錄一下Python命名空間的知識,可參考Python命名空間的本質 - windlaughing - 博客園。
命名空間查找順序:
1.局部命名空間:記錄了函數的變量,包括函數的參數和局部定義的變量,可使用locals()訪問,只讀(這個存疑,官方文檔位于Python locals() - Python Standard Library););
2.全局命名空間:記錄了模塊的變量,包括函數、類、其它導入的模塊、模塊級的變量和敞亮,可使用globals()進行訪問,可修改【全局命名空間里的函數似乎可以直接訪問,變量則需要通過globals()["變量名"]訪問,這點待考證】;
3.內置命名空間:任何模塊均可訪問它,它存放著內置的函數和異常;
4.如果Python查找不到,會拋出NameError異常;
del()函數只是在命名空間里刪掉該變量,并不會清空內存。
二、在多進程中的可變對象
在Python中使用多進程我用的是multiprocessing庫,可以參考多進程。
具體的問題是:我在主進程中生成一個字典(可變對象),并啟動兩個子進程,傳字典進去,那么在其中一個子進程中改變這個可變對象會不會影響另外一個子進程的值。
以下是實驗代碼:
from multiprocessing import Process import time# 寫數據進程執行的代碼: def write(dictTest):while True:dictTest["Hello"] += 1print ("In function write(), id(dictTest) = %s" % id(dictTest))print ("In function write(), dictTest = %s" % dictTest)time.sleep(1)# 讀數據進程執行的代碼: def read(dictTest):while True:print ("In function read(), id(dictTest) = %s" % id(dictTest))print ("In function read(), dictTest = %s" % dictTest)time.sleep(1)if __name__=='__main__':dictTest = {"Hello":1}pw = Process(target=write, args=(dictTest,))pr = Process(target=read, args=(dictTest,))# 啟動子進程pw,寫入:pw.start()# 啟動子進程pr,讀取:pr.start()# 等待pw結束:pw.join()# pr進程里是死循環,無法等待其結束,只能強行終止:pr.terminate()原理很簡單,寫數據進程不斷給字典賦一個新的值,讀數據進程則不斷讀出新的值,以下為實驗結果:
(python36) dao@dao:~/project/test$ python testMultiProcessing.py In function write(), id(dictTest) = 140319281161848 In function write(), dictTest = {'Hello': 2} In function read(), id(dictTest) = 140319281161848 In function read(), dictTest = {'Hello': 1} In function write(), id(dictTest) = 140319281161848 In function write(), dictTest = {'Hello': 3} In function read(), id(dictTest) = 140319281161848 In function read(), dictTest = {'Hello': 1} In function write(), id(dictTest) = 140319281161848 In function write(), dictTest = {'Hello': 4} In function read(), id(dictTest) = 140319281161848 In function read(), dictTest = {'Hello': 1} In function write(), id(dictTest) = 140319281161848 In function write(), dictTest = {'Hello': 5} In function read(), id(dictTest) = 140319281161848 In function read(), dictTest = {'Hello': 1} In function write(), id(dictTest) = 140319281161848 In function read(), id(dictTest) = 140319281161848 In function read(), dictTest = {'Hello': 1} In function write(), dictTest = {'Hello': 6} In function read(), id(dictTest) = 140319281161848 In function read(), dictTest = {'Hello': 1}可以看出,雖然兩者的ID數是一樣的,表明兩者在內存是一體的,但是兩者的數卻發生了變化,原因待以后察覺吧。
三、多進程通信
如果我們需要在多進程之間通信,比如改變子進程之間的公共字典,可以使用Manager管理的共享數據類型,可以參考Python多進程編程-進程間共享數據(Value、Array、Manager)。
這里放一個我的測試程序:
(python36) dao@dao:~/project/test$ python testMultiProcessing.py In function read(), id(dictTest) = 140054398564280 In function write(), id(dictTest) = 140054398564280 In function write(), dictTest = {'Hello': 2} In function read(), dictTest = {'Hello': 2} In function read(), id(dictTest) = 140054398564280 In function write(), id(dictTest) = 140054398564280 In function read(), dictTest = {'Hello': 3} In function write(), dictTest = {'Hello': 3} In function read(), id(dictTest) = 140054398564280 In function read(), dictTest = {'Hello': 3} In function write(), id(dictTest) = 140054398564280 In function write(), dictTest = {'Hello': 4} In function read(), id(dictTest) = 140054398564280 In function read(), dictTest = {'Hello': 4} In function write(), id(dictTest) = 140054398564280 In function write(), dictTest = {'Hello': 5} In function read(), id(dictTest) = 140054398564280 In function read(), dictTest = {'Hello': 5} In function write(), id(dictTest) = 140054398564280 In function write(), dictTest = {'Hello': 6} In function read(), id(dictTest) = 140054398564280 In function read(), dictTest = {'Hello': 6} In function write(), id(dictTest) = 140054398564280 In function write(), dictTest = {'Hello': 7} In function read(), id(dictTest) = 140054398564280 In function read(), dictTest = {'Hello': 7}可以看出,這個是符合使用要求的。
【已完結】
總結
以上是生活随笔為你收集整理的snmpset对象不可写_[Python]可变对象与多进程通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 布林通道参数用20还是26_“布林强盗”
- 下一篇: websocket python爬虫_p