Установка значения атрибута для унаследованного класса, когда он не является аргументом в __init__ - PullRequest
0 голосов
/ 14 мая 2019

Я создаю класс, который будет коллекцией других классов, собранных вместе, когда он будет инициирован.

Прямо сейчас, функция <strong>init</strong> для моего класса выглядит следующим образом:

class RandomForest():
    def __init__(self, n_estimators=10, min_leaf=5, sample_size = 2/3, min_impurity=1e-5):
    self.n_estimators = n_estimators
    self.tree         = None
    self.min_leaf     = min_leaf
    self.sample_size  = sample_size
    self.min_impurity = min_impurity
    self.trees        = [self.tree(min_leaf=self.min_leaf, impurity_threshold=self.min_impurity) for i in range(n_estimators)]

Идея состоит в том, что будут два подкласса класса RandomForest, которые будут использовать разные классы для атрибута self.tree, и это то, что я хотел бы изменить при инициации для каждого из них.

Прямо сейчас у меня есть это для подкласса Random Forest:

class RandomForestRegressor(RandomForest):
    def __init__(self):
        self.tree = DecisionTreeRegressor
        super().__init__() 

В своей голове я устанавливаю значение self.tree для класса, который хочу инициировать, и тогда self.trees будет списком с 10 отдельными экземплярами DecisionTreeRegressor(), но вместо этого я получаю ошибку сообщение:

TypeError: 'NoneType' object is not callable

Так что, очевидно, значение self.tree не обновляется.

Кроме того, я не хочу, чтобы это был выбор, который делает пользователь, когда класс инициируется, и он должен быть установлен автоматически без их выбора.

Как правильно установить этот атрибут для унаследованного класса Random Forest?

** РЕДАКТИРОВАТЬ: ** Это будет сделано в Python 3.

Ответы [ 2 ]

2 голосов
/ 14 мая 2019

Вы устанавливаете значение, но затем вызываете метод super, который немедленно устанавливает его в None, следовательно, возникает ошибка.

Решение состоит в том, чтобы просто установить его после вызова super.

1 голос
/ 14 мая 2019

Если вы установите дерево атрибутов перед вызовом инициализации суперкласса, оно будет у вас в экземпляре класса, но при вызове после инициализации суперкласса вы также делаете:

    self.tree         = None

, которые заменяют ранее установленное вами дерево значением None.

Вы можете:

  • вызовите super().__init__() перед установкой переменной дерева, если ничто не зависит от значения self.tree
class SupClass:
    def __init__():
        self.tree = None

class SubClass(SupClass):
    def __init__():
        super().__init__() # It would set self.tree = None
        self.tree = Something # It will set self.tree to Something

  • Оберните условно установочное дерево в ваш суперкласс следующим образом: self.tree = self.tree if hasattr(self, 'tree') else None, который установит None, только если ранее не было установлено self.tree.
class SupClass:
    def __init__():
        self.tree = self.tree if hasattr(self, 'tree') else None  # Note, it check if value is defined before, in other case you may need to check if value is not None too.

class SubClass(SupClass):
    def __init__():
        self.tree = Something # It will set self.tree to Something
        super().__init__() # It will leave Something, because there is value

  • положить его как аргумент инициализации SupClass
class SupClass:
    def __init__(tree=None):
        self.tree = tree

class SubClass(SupClass):
    def __init__():
        super().__init__(tree=Something) # Note that your SupClass init method has no argument tree, you use it only in superclass init call.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...