Передача собственных данных в рекурсивную функцию

Я пытаюсь установить функцию, чтобы сделать что-то вроде этого

   def __binaryTreeInsert(self, toInsert, currentNode=getRoot(), parentNode=None):

где текущий узел начинается как корень, а затем мы меняем его на другой узел в методе и рекурсивно вызываем его снова.

Тем не менее, я не могу заставить 'currentNode=getRoot()' работать. Если я пытаюсь вызвать функцию getRoot() (как указано выше), она говорит, что я не передаю ей все необходимые переменные, но если я пытаюсь вызвать self.getRoot(), она жалуется, что self является неопределенной переменной. Есть ли способ, которым я могу сделать это без указания рута при вызове этого метода?

РЕДАКТИРОВАТЬ: базовый вариант этого метода уже

if currentNode == None:

поэтому использование этого для установки рута не будет работать

4 ответа

Решение

В то время как arg=None это идиоматическое значение часового Python для непредоставленного аргумента, оно не должно быть None, Например, в Lua идиоматический непредоставленный аргумент является пустой таблицей. Мы можем применить это к этому случаю:

class Foo:
    sentinel = {}
    def bar(self, arg=sentinel):
        if arg is self.sentinel:
            print "You didn't supply an argument!"
        else:
            print "The argument was", arg

f = Foo()
f.bar(123)
f.bar()
f.bar(None)
f.bar({})

Выход:

Аргумент был 123
Вы не предоставили аргумент!
Аргумент был Нет
Аргумент был {}

Это работает для любого случая, кроме явного прохождения Foo.sentinel, так как Foo.sentinel гарантированно иметь уникальный адрес - значение, x is Foo.sentinel верно только тогда, когда х Foo.sentinel:) Таким образом, из-за закрытия мы создали вокруг Foo.sentinel Существует только один объект, который может создать неоднозначную ситуацию, и он никогда не будет использован случайно.

Ты можешь сделать

def __binaryTreeInsert(self, toInsert, currentNode=None, parentNode=None):
   if currentNode is None:
      currentNode = self.getRoot()

...

Когда функция или метод определены, def Строка оценивается сразу, включая любые ключевые аргументы. По этой причине такие вещи, как вызовы функций и изменяемые объекты, обычно не подходят для аргументов по умолчанию.

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

not_provided = object()
def _binaryTreeInsert(self, toInsert, currentNode=not_provided, parentNode=None):
    if currentNode is not_provided:
        currentNode = self.getRoot()
def __binaryTreeInsert(self, toInsert, currentNode=0, parentNode=None):
    if not currentNode: 
        currentNode = self.getRoot()
Другие вопросы по тегам