[英]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.