Получение TypeError: аргумент int() должен быть строкой, байтоподобным объектом или числом, а не ‘NoneType’ при разделении функций класса на несколько ячеек

#python #python-3.x #jupyter-notebook #typeerror

#python #python-3.x #jupyter-notebook #ошибка типа

Вопрос:

Я запускаю код дерева решений в Jupyter Notebook и создал класс с именем DTC. Внутри DTC имеет несколько функций. В Jupyter Notebook я разделил эти функции класса на несколько ячеек, вызвав class DTC(DTC): ... вверху каждой функции в ячейке.

Большинство функций работают, за исключением одной. Ниже приведен код:

 class DTC:
    def __init__(self):
        self.__root = None

...

class DTC(DTC):
    def __predict_what(self,data,node):            
        if len(node.children) == 0 :
            return node.output
        val = data[node.data]       
        if val not in node.children :
            return node.output
 
        return self.__predict_what(data,node.children[val])

class DTC(DTC):
    def prediction(self,X):
        Y = np.array([0 for i in range(len(X))])
        for i in range(len(X)):
            Y[i] = self.__predict_what(X[i],self.__root)
        return Y
 

Функция prediction() выдает ошибку TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType' при попытке запуска. Я поставил диагноз и обнаружил, что это строка с проблемой:

 Y[i] = self.__predict_what(X[i],self.__root)
 

Если я удалю это, функция prediction() может вернуться i . Либо, если я удалю Y[i] без [i] , функция тоже может выполняться.

Чтобы вызвать эту функцию prediction(), я передаю 2D-массив X — classification.prediction(test_data.values)

Одна странная вещь заключается в том, что код работает без проблем, если я запускаю класс и все его функции в одной ячейке Jupyter Notebook.

Есть идеи, почему это происходит и каково исправление? Спасибо.

Ответ №1:

Каждая ячейка выполняется как отдельный оператор, работающий в одной и той же глобальной сети enviromnet.

Первое, что я бы сказал, это то, что вы делаете, ужасно — заставлять класс наследовать предыдущую версию самого себя — плохой способ организовать код. Это просто кажется «хакерским».

Как вы сами сказали, строка, выдающая ошибку, является :

 Y[i] = self.__predict_what(X[i],self.__root)
 

Но в коде, который вы предоставили, вы никогда не устанавливаете self.__root ; Он всегда имеет значение None только в вашем первом операторе class.

что означает, когда вы вызываете self.__predict_что — вы всегда вызываете :

 Y[i] = self.__predict_what(X[i],None)
 

Комментарии:

1. Спасибо, Тони, это четкое объяснение. Я согласен, что не рекомендуется делать это таким образом, но я должен, чтобы описать каждую из моих функций в markdown в Jupyter Notebook. Я не думаю, что для этого есть обходной путь?

2. @user3118602 — Я никогда не использовал markdown в Jupyter, поэтому не могу сказать, что есть лучший способ. Я бы не стал использовать одни и те же имена классов — но это только я.