【问题标题】:How to inherit all functionality of a parent class?如何继承父类的所有功能?
【发布时间】:2018-12-02 08:40:55
【问题描述】:

我正在尝试将 ete3.Tree 的所有功能继承到名为 TreeAugmented 的新类中,但并非所有方法和属性都可用?

__init__super 中有什么我应该做的吗?似乎super 必须指定单独的属性,如The inheritance of attributes using __init__

我可以在名为 tree 的类中有另一个对象,我在其中存储来自 ete3.Tree 的所有内容,但我希望能够将这些对象与 ete3 包中的函数一起使用。

有没有办法只继承父类的所有内容?

import ete3
newick = "(((petal_width:0.098798,petal_length:0.098798):0.334371,"
         "sepal_length:0.433169):1.171322,sepal_width:1.604490);"

print(ete3.Tree(newick).children)
# [Tree node '' (0x1296bf40), Tree node 'sepal_width' (0x1296bf0f)]

class TreeAugmented(ete3.Tree):
    def __init__(self, name=None, new_attribute=None):
        self.name = name # This is an attribute in ete3 namespace
        self.new_attribute = new_attribute

x = TreeAugmented(newick)
x.children

追溯

AttributeError                            Traceback (most recent call last)
<ipython-input-76-de3016b5fd1b> in <module>()
      9
     10 x = TreeAugmented(newick)
---> 11 x.children

~/anaconda/envs/python3/lib/python3.6/site-packages/ete3/coretype/tree.py in _get_children(self)
    145
    146     def _get_children(self):
--> 147         return self._children
    148     def _set_children(self, value):
    149         if type(value) == list and \

AttributeError: 'TreeAugmented' object has no attribute '_children'

【问题讨论】:

  • 你通常调用基类的__init__()。具体取决于 Python 版本。
  • 我正在使用 Python 3.6,并计划在我使用的所有包也迁移后升级到 3.7。所以在__init__ 中我会调用ete3.Tree 类?
  • 如果您查看您发布的链接的接受答案,它会显示代码在没有显式调用所有属性的情况下工作。父类需要的任何参数仍然是必需的,所以不要忘记也传递它们。

标签: python class object inheritance super


【解决方案1】:

有没有办法只继承父类的所有内容?

默认情况下就是这样。子类继承了它没有覆盖的东西。

您的子类几乎是正确的。由于您覆盖了__init__ 方法,因此您要确保父类的__init__ 方法也被调用。

这是使用super实现的:

class TreeAugmented(ete3.Tree):
    def __init__(self, newick=None, name=None, format=0, dist=None, support=None, new_attribute=None):
        super().__init__(newick=newick, format=format, dist=dist, support=support, name=name)
        self.new_attribute = new_attribute

不需要self.name = name,因为它是在super().__init__() 中完成的。您只需要关心您的孩子班级的具体情况。

使用 *args/**kwargs

此外,由于您没有触及所有这些父级 init 属性,因此您可以使用 args/kwargs 使代码更清晰:

class TreeAugmented(ete3.Tree):
    def __init__(self, newick=None, new_attribute=None, *args, **kwargs):
        super().__init__(newick=newick, *args, **kwargs)
        self.new_attribute = new_attribute

在此示例中,我将newick 保留为第一个位置,并决定所有其他参数都在new_attribute 之后或者是关键字参数。

 设置父类参数

如果您不想公开父类的所有参数,则不必公开。例如,如果您想创建一个只会执行format 3 "all branches + all names" 的子类,您可以通过编写强制格式:

class TreeAugmented(ete3.Tree):
    def __init__(self, newick=None, name=None, dist=None, support=None, new_attribute=None):
        super().__init__(newick=newick, format=3, dist=dist, support=support, name=name)
        self.new_attribute = new_attribute

(这只是一个展示常见做法的虚拟示例。在您的上下文中可能没有意义。)

【讨论】:

  • *args, **kwargs
  • 我收到newick 的重复错误,但我只在调用TypeError: __init__() got multiple values for argument 'newick' 中使用过一次
  • 对不起。我的错。不要将self 传递给super().__init__()。答案固定。
  • 谢谢! self 是否会因为 newick 在两者的参数中而引发这种行为?
  • self 和 newick 是第一个位置参数。该方法期望(self,newick,...),并且由于它是绑定的,所以self是自动传递的,但是由于我也传递了它(我的错误),该方法接收(self,self,newick=whatever),然后映射自我对自我,自我对新人,然后新人对新人......因此错误。我希望我说得通。
猜你喜欢
  • 2015-11-25
  • 2013-11-29
  • 1970-01-01
  • 2015-09-10
  • 1970-01-01
  • 1970-01-01
  • 2013-04-11
  • 2015-03-14
  • 1970-01-01
相关资源
最近更新 更多