简体   繁体   中英

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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