文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏

这篇简短的文章是我再次回归写作的开始。我只是想写一点有意思的东西,就像我之前提到的Python的继承,Java/c#都没有的继承。

多重继承

Python最突出的特点是他具有其他语言没有的多重继承,并且实现得非常优雅和强大(参见这篇文章视频)。

这个功能非常的酷,但是大多数时候,这个功能也伴随着危险,如果没有写明参数的列别并且用super()直接调用继承,尤其是__init__(),就很容易得到一个不兼容的类注入到MRO,下面让我看一个例子:

第 1 段(可获 1.7 积分)
class Base:
    def __init__(self, a):
        self.a = a


class One(Base):
    def __init__(self, a, b):
        super().__init__(a)
        self.b = b


class Half(Base):
    def __init__(self, a, c):
        super().__init__(a)
        self.c = c


class Multi(One, Half):
    def __init__(self, a, b, c):
        # there is no super() call that can work here.

在创建Multi的同时, MRO也构建了 Multi, One, Half, Base. Multi 不能用调用super(),但是  __init__()还是能用的.这些东西在特殊设计之后也能被继承 (这个不在本篇讨论的范围,也许近期会更新), 否则你很可能最终会一团糟. 如果你想要合并你无法控制的两个类, 你需要看看他们的源代码,看看他们是这种设计。

第 2 段(可获 1.08 积分)

这也是为什么大部分使用多重继承的人建议,只有在继承列表中的第一个类才被接受,其他的类应该作为这个类的一部分. 我也会说如果你能用代理替代继承,那就不用够用继承. 上面两条建议将有助于你避免上面的问题。

类级别属性的继承

Python中的类不只是像其他语言那样继承实例的API(字段和常规方法); classmethods, staticmethods, 和其他类级别的属性也能被子类所继承。.

第 3 段(可获 1.29 积分)

再次强调,这可能是非常有用,特别是一个类可以是任何对象 (类的反射是和其他语言不一样的). 不过这也有潜在的风险.

例如,你有一个使用工厂方法创建一个实例的类方法(classmethod).嗯,你可以从一个子类中调用它,假设它将创建子类的一个实例,但如果子类需要其构造函数中的额外参数,它就不会工作。

第 4 段(可获 1.19 积分)

最后

就像你看到的, Python的继承能力绝对比其他很多主流语言要强大。但这也带来了潜在的危险

我注意到这在其他语言的设计中进行了权衡, 并且这也不是Python的缺陷; 这只是一个需要注意一下的事情。

第 5 段(可获 0.75 积分)

文章评论

CY2
不是说 Java 才是最好的编程语言吗