[英]How to use a decorator to modify mutable class variables?
我有以下代碼:
class X(object):
items = []
class Y(X):
pass
class Z(X):
pass
我正在嘗試創建一個裝飾器,該裝飾器僅將一個對象添加到Y的“項目”列表中。 所以下面的代碼,
@addItems
class Y(X):
pass
應該在Y.items后面附加一些內容(例如,整數1),但不要修改X.items,Z.items或X的任何其他子類。基本上,Y.items應該具有items = [1]
但X.items和Z.items都應具有items = []
。 這是我創建的裝飾器函數定義,旨在實現該目標:
def addItems(cls):
cls.items.append(1)
return cls
但是,這不起作用-當我使用裝飾器時,它最終會修改X和X的所有其他子類的“項目”列表。這有什么用? 我知道Python的類屬性在X的所有實例之間共享,但是,我不知道子類會受到影響。 也許這種行為只發生在可變屬性上?
實現目標的正確方法是什么?
問題不在於裝飾器。 您對items
屬性的存儲位置/方式存在誤解。 Y
和Z
沒有自己的items
屬性。 而是只有一個items
屬性。 您在X
上定義了它,如果執行Y.items
(或Z.items
),則由於在子類上找不到該屬性,因此會在超類上動態查找它。 如果你X.items is Y.items
你會看到它演算值為真---只有一個items
清單。 這意味着,當您對其進行修改時,所有類都會看到該修改。
如果要為每個班級提供自己的items
列表,則必須為每個班級提供自己的items
列表:
class X(object):
items = []
class Y(object):
items = []
class Z(object):
items = []
除非您告知,否則Python絕不會復制任何內容。 僅僅因為您定義了一個繼承自具有屬性的類的子類,但這並不意味着Python會為該子類創建該屬性的新副本。 它只是重復使用超類中的同一對象。
如果您想“神奇地”為每個類賦予自己的項目屬性,則可以在裝飾器中進行操作:
def addItems(cls):
cls.items = []
cls.items.append(1)
return cls
這首先將類的items
設置為空列表。 這實際上將屬性設置在它所操作的特定類上,而不是在任何子類或超類上。 現在,當您訪問它時,它將按預期工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.