Я пытаюсь наследовать все функциональные возможности от ete3.Tree
в мой новый класс под названием TreeAugmented
но не все методы и атрибуты доступны?
Есть ли что-то, что я должен делать в __init__
с super
? Кажется, что с super
вы должны указать отдельные атрибуты, например, в Наследование атрибутов с помощью __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'
Есть ли способ наследовать все от родительского класса?
Это так, по умолчанию. Класс child наследует то, что он не отменяет.
Вы класс ребенка почти правильный. Поскольку вы переопределяете метод __init__
, вы хотите убедиться, что также __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__()
. Все, что вам нужно позаботиться, - это то, что характерно для вашего класса детей.
Кроме того, поскольку вы не трогаете все эти родительские атрибуты 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
или являются аргументами ключевого слова.
Вам не нужно выставлять все параметры из родительского класса, если вы этого не хотите. Например, если вы хотите создать дочерний класс, который будет делать только формат 3 "все ветки + все имена", вы можете форсировать формат, написав:
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'