Usando self.xxxx como parámetro predeterminado – Python

Hola, estoy tratando de simplificar uno de mis problemas con la tarea y mejorar un poco el código. Lo que estoy trabajando es un árbol de búsqueda binario. Ahora mismo tengo una función en mi clase Tree() que encuentra todos los elementos y los pone en una lista.

 tree = Tree() #insert a bunch of items into tree 

luego uso mi función makeList () para tomar todos los nodos del árbol y colocarlos en una lista. Para llamar a la función makeList() , hago tree.makeList(tree.root) . A mi me parece un poco repetitivo. Ya estoy llamando al objeto tree. con tree. así que el tree.root es solo un desperdicio de escribir un poco.

En este momento la función makeList es:

  def makeList(self, aNode): if aNode is None: return [] return [aNode.data] + self.makeList(aNode.lChild) + self.makeList(aNode.rChild) 

Me gustaría hacer que la entrada aNode sea un parámetro predeterminado como aNode = self.root (que no funciona) de esa manera podría ejecutar la función con esto, tree.makeList() .

La primera pregunta es, ¿por qué no funciona?
La segunda pregunta es, ¿hay alguna manera de que funcione? Como puede ver, la función makeList() es recursiva, por lo que no puedo definir nada al principio de la función o obtengo un bucle infinito.

EDITAR Aquí está todo el código solicitado:

 class Node(object): def __init__(self, data): self.data = data self.lChild = None self.rChild = None class Tree(object): def __init__(self): self.root = None def __str__(self): current = self.root def isEmpty(self): if self.root == None: return True else: return False def insert (self, item): newNode = Node (item) current = self.root parent = self.root if self.root == None: self.root = newNode else: while current != None: parent = current if item < current.data: current = current.lChild else: current = current.rChild if item < parent.data: parent.lChild = newNode else: parent.rChild = newNode def inOrder(self, aNode): if aNode != None: self.inOrder(aNode.lChild) print aNode.data self.inOrder(aNode.rChild) def makeList(self, aNode): if aNode is None: return [] return [aNode.data] + self.makeList(aNode.lChild) + self.makeList(aNode.rChild) def isSimilar(self, n, m): nList = self.makeList(n.root) mList = self.makeList(m.root) print mList == nList 

larsmans contestó tu primera pregunta

Para su segunda pregunta, ¿puede simplemente mirar antes de saltar para evitar la recursión?

 def makeList(self, aNode=None): if aNode is None: aNode = self.root treeaslist = [aNode.data] if aNode.lChild: treeaslist.extend(self.makeList(aNode.lChild)) if aNode.rChild: treeaslist.extend(self.makeList(aNode.rChild)) return treeaslist 

No funciona porque los argumentos predeterminados se evalúan en el momento de la definición de la función, no en el momento de la llamada:

 def f(lst = []): lst.append(1) return lst print(f()) # prints [1] print(f()) # prints [1, 1] 

La estrategia común es utilizar un parámetro predeterminado None . Si None es un valor válido, use un centinela de singleton:

 NOTHING = object() def f(arg = NOTHING): if arg is NOTHING: # no argument # etc. 

Si desea tratar None como un argumento válido, puede usar un parámetro **kwarg .

 def function(arg1, arg2, **kwargs): try: arg3 = kwargs['arg3'] except KeyError: arg3 = default # Continue with function function("amazing", "fantastic") # uses default function("foo", "bar", arg3=None) # Not default, but None function("hello", "world", arg3="!!!")