开发者

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开发者_JS百科 to a different node in the method and recursivly call it again.

However, i cannot get the 'currentNode=getRoot()' to work. 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. 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. In Lua, for instance, the idiomatic non-supplied argument is an empty table. 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.


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. 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:

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()
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜