将self数据传入递归函数

1 投票
4 回答
2680 浏览
提问于 2025-04-15 20:25

我正在尝试设置一个函数,想要实现类似这样的功能:

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

在这个函数中,当前节点一开始是根节点,然后我们在方法里把它改成其他节点,并递归地再次调用这个函数。

但是,我无法让 'currentNode=getRoot()' 这个部分正常工作。如果我尝试像上面那样调用 getRoot() 函数,它会提示我没有提供所有必需的变量;而如果我尝试调用 self.getRoot(),它又会抱怨说 self 是一个未定义的变量。有没有办法在调用这个方法时不需要指定根节点呢?

补充说明:这个方法的基本情况已经设置好了:

if currentNode == None:

所以用这个来设置根节点是行不通的。

4 个回答

0

你可以这样做:

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

...
0

当你定义一个函数或者方法时,def这一行会立刻被执行,包括任何关键字参数。因此,像函数调用和可变对象这样的东西通常不适合用作默认参数。

解决这个问题的方法是使用一个哨兵值。None是最常用的,但如果None本身也是一个有效值,你可以使用其他的哨兵值,比如:

not_provided = object()
def _binaryTreeInsert(self, toInsert, currentNode=not_provided, parentNode=None):
    if currentNode is not_provided:
        currentNode = self.getRoot()
2

在Python中,arg=None是一个常用的方式,用来表示一个没有提供的参数,但其实它不一定非得是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({})

输出:

The argument was 123
You didn't supply an argument!
The argument was None
The argument was {}

这个方法在任何情况下都有效,除了当你明确传入Foo.sentinel的时候,因为Foo.sentinel的地址是唯一的——这意味着,x is Foo.sentinel 只有在x真的等于Foo.sentinel时才会为真 :) 这样,由于我们对Foo.sentinel的封闭性,只有一个对象可能会造成混淆的情况,而且它不会被意外使用。

撰写回答