繁体   English   中英

Python类继承 - Base由子类修改

[英]Python class inheritance - Base is modified by a subclass

假设我有一个名为Test的类,带有属性项。 然后我创建一个名为Best的子类。 其中有一个修改classes属性项的方法。 但它甚至修改了Testitems ,我只修改了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

itemsTest类属性。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM