简体   繁体   English

将自身数据传递给递归函数

[英]passing self data into a recursive function

I'm trying to set a function to do something like this 我正在尝试设置一个函数来做这样的事情

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

where current node starts as root, and then we change it to a different node in the method and recursivly call it again. 当前节点从根开始,然后在方法中将其更改为另一个节点,然后再次递归调用它。

However, i cannot get the 'currentNode=getRoot()' to work. 但是,我无法使“ currentNode = getRoot()”正常工作。 If i try calling the funcion getRoot() (as above) it says im not giving it all the required variables, but if i try to call self.getRoot() it complains that self is an undefined variable. 如果我尝试调用funcion getRoot()(如上所述),则表示未提供所有必需的变量,但是如果我尝试调用self.getRoot(),则抱怨self是未定义的变量。 Is there a way i can do this without having to specify the root while calling this method? 有没有一种方法可以在我不必调用此方法时指定根的情况下做到这一点?

EDIT: The base case of this method is already 编辑:此方法的基本情况已经

if currentNode == None:

so using that to set the root wouldn't work 所以用那个来设置根是行不通的

While arg=None is the idiomatic Python sentinel value for an non-supplied argument, it doesn't have to be None . 虽然arg=None是用于非提供的参数的惯用的Python标记值,它不必须None In Lua, for instance, the idiomatic non-supplied argument is an empty table. 例如,在Lua中,惯用的不提供的参数是一个空表。 We can actually apply that to this case: 实际上,我们可以将其应用于这种情况:

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({})

Output: 输出:

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

This works for any case except explicitly passing Foo.sentinel , because Foo.sentinel is guaranteed to have a unique address -- meaning, x is Foo.sentinel is only true when x is Foo.sentinel :) Thus, due to the closure we've created around Foo.sentinel , there is only one object that can create an ambiguous situation, and it will never be used by accident. 这适用于除显式传递Foo.sentinel之外的任何情况,因为Foo.sentinel保证具有唯一地址-意味着, x is Foo.sentinel 当x Foo.sentinel才是 Foo.sentinel :)因此,由于闭包,我们在Foo.sentinel周围创建的对象中,只有一个对象会造成模棱两可的情况,并且永远不会偶然使用它。

You can do 你可以做

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

...

When a function or method is defined, the def line is evaluated immediately, including any keyword arguments. 定义函数或方法后,将立即评估def行,包括所有关键字参数。 For this reason, things like function calls and mutable objects are usually not appropriate for default arguments. 因此,函数调用和可变对象之类的内容通常不适用于默认参数。

The solution is instead to use a sentinel value. 解决方案是使用哨兵值。 None is most common, but for the cases that None would be a valid value, you can use another sentinel, for example: 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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM