使用 self. xxxx 作为默认参数 -Python

我试图简化我的一个家庭作业问题,并使代码更好一点。和我一起工作的是个二叉查找树。现在,我的 Tree()类中有一个函数,它可以找到所有元素并将它们放入一个列表中。

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

然后使用 makList ()函数从树中获取所有节点,并将它们放在一个列表中。 为了调用 makeList()函数,我执行 tree.makeList(tree.root)。对我来说,这似乎有点重复。我已经使用 tree.调用了 tree 对象,所以使用 tree.root只是浪费了一点输入的时间。

现在,makList 函数是:

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

我想使 aNode 输入成为一个默认参数,比如 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
42866 次浏览

It doesn't work because default arguments are evaluated at function definition time, not at call time:

def f(lst = []):
lst.append(1)
return lst


print(f()) # prints [1]
print(f()) # prints [1, 1]

The common strategy is to use a None default parameter. If None is a valid value, use a singleton sentinel:

NOTHING = object()


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

larsmans answered your first question

For your second question, can you simply look before you leap to avoid recursion?

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

If you want to treat None as a valid argument, you could use a **kwarg parameter.

def function(arg1, arg2, **kwargs):
kwargs.setdefault('arg3', default)
arg3 = kwargs['arg3']
    

# Continue with function


function("amazing", "fantastic") # uses default
function("foo", "bar", arg3=None) # Not default, but None
function("hello", "world", arg3="!!!")

I have also seen ... or some other singleton be used like this.

def function(arg1, arg2=...):
if arg2 is ...:
arg2 = default