Question

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

Was it helpful?

Solution

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.

OTHER TIPS

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()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top