本文環境:Python 2.7
一個類的三個對象實例的屬性被同時修改
有段代碼如下:
class task_queue: queue=[] def append(self,obj): self.queue.append(obj) def print_queue(self): print self.queue if __name__=="__main__": a=task_queue() b=task_queue() c=task_queue() a.append('tc_1') a.print_queue() b.print_queue() c.print_queue()
我們期望在隊列 a 中插入 tc_1,結果 b 和 c 也被同時操作了,這並不是我們所期望的
['tc_1'] ['tc_1'] ['tc_1']
static
這種行為很像靜態變量的行為,可是 Python 中並沒有 static 關鍵字,這是怎么回事?
Java 和 C++ 中的 static 關鍵字有多種用法
其中,如果 static 去修飾一個類的屬性,那么該屬性就不是被各個對象所持有,而是一片公共的區域
利用這種方法,我們可以在構造函數中對一個靜態變量 ++ 以查看它被實例化了多少次
class a(){ static private count public a(){ this.count++ } public static instance_count(){ System.out.println(this.count) } }
回到 Python
Python 中並沒有訪問限定符 static,這種機制在 Python 中被稱為 類的屬性 和 對象的屬性
第一段代碼中的 queue 在類的聲明中被初始化為空,這是 類的屬性
a.append() 之后,queue 中添加了 'tc_1',而 b 和 c 獲取的 queue 依然是公共的 類的屬性
如何讓這個屬性變為對象自己的呢?改動如下:
class task_queue: def __init__(self): self.queue=[] def append(self,obj): self.queue.append(obj) def print_queue(self): print self.queue
在構造對象實例時構造對象自己的屬性 queue
['tc_1'] [] []
另一個例子
class a(): num = 0 if __name__=="__main__": obj1 = a() obj2 = a() print obj1.num, obj2.num, a.num obj1.num += 1 print obj1.num, obj2.num, a.num a.num += 2 print obj1.num, obj2.num, a.num
實例化 obj1 和 obj2 的時候,他們都沒有對屬性 num 進行操作,所以打印出來的都是類 a 的屬性 num,也就是 0
后來 obj1 對自己的 num 進行 +1 之后,與類的屬性脫離了關系,屬性 num 就變成對象 obj1 自己的屬性,而 obj2 嘗試打印屬性 num 的時候還是從類的屬性中去讀取
第三段中,類的屬性 +2 后,obj1.num 沒有受到影響,而 obj2 嘗試讀取 num 屬性時,依舊從類中去拿,所以它拿到的 num 是2
0 0 0 1 0 0 1 2 2