[英]Python class inheritance issue occurs when using base class to assign attributes of subclass
[英]Python class inheritance - Base is modified by a subclass
假設我有一個名為Test
的類,帶有屬性項。 然后我創建一個名為Best
的子類。 其中有一個修改classes屬性項的方法。 但它甚至修改了Test
的items
,我只修改了Best
items
。
class Test():
items = []
class Best(Test):
def method(self):
type(self).items.append("a test")
>>> Best().method()
>>> Best.items
["a test"]
>>> Test.items
["a test"] # This is what I don't want.
您已將items
聲明為超類本身的屬性,因此Test的所有實例及其子類將共享相同的列表。 而是在Test的__ init __方法中聲明它,因此每個實例有一個列表。
在Best中,只需附加到self.items
,只會更新Best實例的列表。
class Test(object):
def __ init __(self)
self.items = []
class Best(Test): # Best must inherit from Test
def method(self):
self.items.append("a test")
在Python中,您可以通過使用“私人”成員獲得您所要求的內容......
class Base(object):
def __init__(self):
self.__mine = 42 # note the double underscore
def baseMethod(self):
return self.__mine
class Derived(Base):
def __init__(self):
Base.__init__(self)
self.__mine = 99
def derivedMethod(self):
return self.__mine
obj = Derived()
print(obj.baseMethod(), obj.derivedMethod()) ## ==> 42, 99
這是有效的,因為在編譯時 Python將在編譯Base
時用_Base__mine
替換名稱__mine
,在編譯Derived
時用_Derived__mine
。
但請注意,在Python中,雖然根據我的經驗這是可行的,但它並不經常使用。 由於“鴨子打字”和授權,在許多情況下派生一個類是不需要的,這在C ++或Java等語言中是不可能的。
你的Best
類正在修改Test
(我認為它應該繼承),因為Best
沒有自己的items
列表。 當您訪問Best.items
,您將訪問從中繼承的列表(即來自Test
類)。 如果你想要一個不同的列表,你需要在子類Best
顯式創建它:
class Best(Test):
items = [] # hide the inherited list with our own list
# ...
唯一可行的方法是在子類上創建一個新items
- 這個新列表還來自哪里? type(self)
也是多余的。 查找機制在類上查找屬性,如果它無法在實例上找到屬性。 更好的是,如果您不需要實例,則將該方法聲明為類方法。
例如。
class Test:
items = []
@classmethod
def method_test(cls):
cls.items.append('test')
class Best(Test):
items = []
@classmethod
def method_best(cls):
cls.items.append('best')
Test.method_test()
assert Test.items == ['test']
assert Best.items == []
Test.items = []
Best.method_test()
Best.method_best()
assert Test.items == []
assert Best.items == ['test', 'best']
需要注意的是method_test
工作在Best
類從調用時Best
的類。
您的代碼不符合您的描述。
首先, Best
不是Test
的子類。
對於另一個Best.method()
產生
NameError: name 'self' is not defined
items
是Test
類屬性。
t = Test()
t.items.append(1)
改變Test.items
。
如定義的B.items
給出一個AttributeError
。
即使我改變了:
class Best():
def method(self):
...
Best.method()
沒有運行; method
是一個實例方法。 我需要使用Best().method()
。 但后來我得到了items
AttributeError
。
class Best(Test):
def method(self):
...
做你想做的事。 Best().method()
修改Test.items
- 因為Test
類屬性與子類共享。
如其他答案所示,只需定義Best
items
,即可將其值與Test
類屬性分離
class Best(Test):
items = ['other']
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.