0

class BaseA(object):
    authors = ['a', 'b']
    author_list = authors

class BaseB(object):
    authors = ['a', 'b']

    def __init__(self, *arg, **kwargs):
        self.author_list = self.authors

class ChildA(BaseA):
    authors = ['c', 'd']

class ChildB(BaseB):
    authors = ['c', 'd']

child_a = ChildA()
child_b = ChildB()
print(child_a.author_list)
print(child_b.author_list)
>>> ['a', 'b']
>>> ['c', 'd']

代码有什么不同?为什么我会得到不同的结果?

我很困惑为什么不覆盖父 author_list 属性。

你能告诉我python继承的原理吗?

4

4 回答 4

4

块内的材料class是类本身的一部分,并且在您定义类时执行一次。材料 in__init__是每个实例的,每次实例化类时每个实例执行一次。

在您的第一个示例 ( BaseA) 中,您创建一个类属性authors,然后创建另一个author_list指向相同值的属性。这就对了。没有别的事情发生。ChildA继承自的事实BaseA不会导致author_list = authors重新执行。 author_list结束并完成了一次BaseA定义。

在您的第二个示例 ( BaseB) 中,您创建了一个类属性authors。然后在__init__你创建一个指向相同值的新实例属性。由于您在 中执行此操作__init__,因此会为每个实例重新执行此操作。所以当你实例化时BaseB,它会得到新的属性。

请注意,您正在检查实例child_achild_b. 如果您在类 (ChildA.author_listChildB.author_list) 上检查它们,您将看到两者具有相同的值 ( ['a', 'b'])。因为您在 ChildB 中的操作发生在 中__init__,所以它仅在您实际实例化该类时生效。

于 2013-01-12T08:09:09.530 回答
0

不同之处在于,在第二个示例中,author_list是在创建对象实例时设置的。

当你定义类时BaseA,你定义了类成员author_list,就是这样,所以当你创建一个ChildA什么都没有发生的实例时author_list。它只是继承。

当您定义BaseB时没有成员author_list。在创建 的实例时将其创建为实例变量BaseB。因此,当您创建相同事情的实例时ChildB,会发生相同的事情,但是由于authors被重新定义,那么它将使用的新值authors

于 2013-01-12T08:08:23.420 回答
0

编写 Python 代码的推荐方法:

class BaseA(object):
    def __init__(self):
        self.authors = ['a', 'b']

class BaseB(object):
    def __init__(self):
        self.authors = ['a', 'b']

class ChildA(BaseA):
    def __init__(self):
        self.authors = ['c', 'd']
    
class ChildB(BaseB):
    def __init__(self):
        self.authors = ['c', 'd']


child_a = ChildA()
child_b = ChildB()
print(child_a.authors)
print(child_b.authors)
>>> ['c', 'd']
>>> ['c', 'd']

调用超类(Base Parent 类)的推荐方法:

class BaseA(object):
    def __init__(self):
        self.authors = ['a', 'b']

class BaseB(object):
    def __init__(self):
        self.authors = ['a', 'b']

class ChildA(BaseA):
    def __init__(self):
        self.authors = ['c', 'd']
        super().__init__()
    
class ChildB(BaseB):
    def __init__(self):
        self.authors = ['c', 'd']
        BaseB.__init__(self)


child_a = ChildA()
child_b = ChildB()
print(child_a.authors)
print(child_b.authors)
>>> ['a', 'b']
>>> ['a', 'b']

在结尾使用一个下划线的深奥超类调用__init__ (__init_)

class BaseA(object):
    def __init__(self):
        self.authors = ['a', 'b']

class BaseB(object):
    def __init__(self):
        self.authors = ['a', 'b']

class ChildA(BaseA):
    def __init_(self):
        self.authors = ['c', 'd']
    
class ChildB(BaseB):
    def __init_(self):
        self.authors = ['c', 'd']


child_a = ChildA()
child_b = ChildB()
print(child_a.authors)
print(child_b.authors)
>>> ['a', 'b']
>>> ['a', 'b']

警告

使用深奥的超类调用会导致失去对子变量的所有访问权限!

对子类(Child 类)中的方法的访问仍然可以访问,但对子类(Child 类)中变量的所有访问都将完全丢失。

于 2021-01-08T23:54:09.933 回答
0

在您的 BaseB__init__函数中,您调用的是 Child 的作者,而不是 Parent 的作者。如果你想打电话给父母的作者,你会使用BaseB.authors而不是self.authors

class BaseA(object):
    authors = ['a', 'b']
    author_list = authors

class BaseB(object):
    authors = ['a', 'b']

    def __init__(self, *arg, **kwargs):
        self.author_list = BaseB.authors

class ChildA(BaseA):
    authors = ['c', 'd']

class ChildB(BaseB):
    authors = ['c', 'd']

child_a = ChildA()
child_b = ChildB()
print(child_a.author_list)
print(child_b.author_list)
>>> ['a', 'b']
>>> ['a', 'b']

如果您将连接 ParentB 和 ChildB 的作者,那么您将同时使用BaseB.authorsand self.authors

class BaseA(object):
    authors = ['a', 'b']
    author_list = authors

class BaseB(object):
    authors = ['a', 'b']

    def __init__(self, *arg, **kwargs):
        self.author_list = BaseB.authors + self.authors

class ChildA(BaseA):
    authors = ['c', 'd']

class ChildB(BaseB):
    authors = ['c', 'd']

child_a = ChildA()
child_b = ChildB()
print(child_a.author_list)
print(child_b.author_list)
>>> ['a', 'b']
>>> ['a', 'b', 'c', 'd']

覆盖

class BaseA(object):
    authors = ['a', 'b']
    author_list = authors

class BaseB(object):
    authors = ['a', 'b']

    def __init__(self, *arg, **kwargs):
        self.author_list = self.authors

class ChildA(BaseA):
    authors = ['c', 'd']
    def __init__(self, *arg, **kwargs):
        self.author_list = self.authors

class ChildB(BaseB):
    authors = ['c', 'd']

child_a = ChildA()
child_b = ChildB()
print(child_a.author_list)
print(child_b.author_list)
>>> ['c', 'd']
>>> ['c', 'd']
于 2021-01-08T22:43:22.640 回答