關於python類屬性和例項屬性的一些細節注意點

張國平發表於2020-03-09

關於python類屬性和例項屬性,簡單來說,類屬性就是在定義類的時候,和類方法同一級別定義的屬性;例項屬性是在__init__例項初始化時候定義屬性。

單純從例項的角度來看, 類屬性和例項屬性都可以在例項中用self.屬性名稱的方法進行訪問更新,相對於在例項方法中的區域性屬性,可以進行例項全域性該屬性修改,很多時候甚至都混用了。

其實類屬性還可以直接用類名.類 屬性名稱方法直接訪問,即時沒有例項化。這個就是不要的類不要import,也會佔用記憶體空間,即便那個類沒有例項化。同時這個類屬性方法的記憶體空間是所有例項化物件共享的,理論上例項物件A更新了類屬性,B中這個屬性也會更新,某個方面就實現跨例項的全域性變數,可以用作例項直接互動。


這裡有一些細節點要注意的,就是如果類屬性是int,string,float,tuple這樣不可變型別,那邊其實每個例項更改的時候,就會新建一個,並不會修改原來的,這些型別的類屬性就是和例項屬性一個樣;而可變型別dict set list,還有例項物件;這些就真正全域性更新,只有一個類的例項物件修改,所有該類的例項物件都會改變。


最後還有一點,很容易忽視的,就是如果使用python Multiprocessing多執行緒處理的時候,不要嘗試用這些類屬性進行通訊,因為可能一個例項在讀,另一個已經修改了。還是用queue,這個是執行緒安全的。


下面程式碼示例說明。

class TreeNode:
    intItem= 5
    StringItem = 'Test'
    listItem = [1,2,3,4]
    Dict = {1:2,2:4}
    def __init__(self, x):
        self.Intval = x
        self.listval= ['A','B']
A = TreeNode(1)
B = TreeNode(2)
print("TreeNode.intItem:%s, TreeNode.listItem:%s" %(TreeNode.intItem,TreeNode.listItem))
print("A:%s, B:%s" %(A.intItem, B.intItem))
print("A:%s, B:%s" %(A.StringItem, B.StringItem))
print("A:%s, B:%s" %(A.listItem, B.listItem))
print("A:%s, B:%s" %(A.Dict, B.Dict))
print("A:%s, B:%s" %(A.listval, B.listval))
A.intItem = 8
A.StringItem = 'Test2'
A.listItem.insert(-1,5)
A.Dict[3] = 9
A.listval.insert(-1,5)
print("========only update A=========")
print("TreeNode.intItem:%s, TreeNode.listItem:%s" %(TreeNode.intItem,TreeNode.listItem))
print("A:%s, B:%s" %(A.intItem, B.intItem))
print("A:%s, B:%s" %(A.StringItem, B.StringItem))
print("A:%s, B:%s" %(A.listItem, B.listItem))
print("A:%s, B:%s" %(A.Dict, B.Dict))
print("A:%s, B:%s" %(A.listval, B.listval))

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22259926/viewspace-2679071/,如需轉載,請註明出處,否則將追究法律責任。

相關文章