Использование self.xxxx в качестве параметра по умолчанию - Python
Я пытаюсь упростить одну из моих домашних задач и сделать код немного лучше. Я работаю с бинарным деревом поиска. Прямо сейчас у меня есть функция в моем классе Tree()
которая находит все элементы и помещает их в список.
tree = Tree()
#insert a bunch of items into tree
затем я использую свою функцию makeList(), чтобы взять все узлы из дерева и поместить их в список. Чтобы вызвать makeList()
, я делаю tree.makeList(tree.root)
. Мне это кажется немного повторяющимся. Я уже вызываю объект tree.
с tree.
так что tree.root
- это просто пустая трата текста.
Прямо сейчас функция makeList:
def makeList(self, aNode):
if aNode is None:
return []
return [aNode.data] + self.makeList(aNode.lChild) + self.makeList(aNode.rChild)
Я хотел бы сделать входной параметр aNode = self.root
параметром по умолчанию, таким как aNode = self.root
(который не работает), чтобы я мог запустить функцию с этим tree.makeList()
.
Первый вопрос: почему это не работает?
Второй вопрос: есть ли способ, которым это может работать? Как видите, makeList()
является рекурсивной, поэтому я не могу ничего определить в начале функции, или я получаю бесконечный цикл.
РЕДАКТИРОВАТЬ Вот весь код в соответствии с просьбой:
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
Ответы
Ответ 1
larsmans ответил ваш первый вопрос
Для вашего второго вопроса вы можете просто взглянуть, прежде чем прыгать, чтобы избежать рекурсии?
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
Ответ 2
Это не работает, потому что аргументы по умолчанию оцениваются во время определения функции, а не во время вызова:
def f(lst = []):
lst.append(1)
return lst
print(f()) # prints [1]
print(f()) # prints [1, 1]
Общая стратегия заключается в использовании параметра None
по умолчанию. Если None
является допустимым значением, используйте однотонный дозор:
NOTHING = object()
def f(arg = NOTHING):
if arg is NOTHING:
# no argument
# etc.
Ответ 3
Если вы хотите рассматривать None
как допустимый аргумент, вы можете использовать параметр **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="!!!")