Your example would work in some programming languages. (For example
C allows this, via pointer references.) The reason it doesn't work here is because of how the semantics of method-calling is defined in Python.
Name binding in Python
When you write
self.data = None
this assigns a new name (self.data) to the object None.
With self.Recur defined as
def Recur(self, node, data):
if node is None:
node = data
the following gives a new name to None in the context of the Recur method:
node.
self.Recur(self.data, data)
However, this new name (node) in the inner scope for the same object has no co-relation to the other name (self.data) in the outer scope.
When you write
node = data
this assigns the name node to a new value, namely the value to which
the name data refers. Again, this does not affect the name
self.data. For more information, check out this blog post.
How to do what you want
On the other hand, if you want Recur to be able to assign a value to any attribute of the test object, it can be done. Here
is one way to achieve it:
class test:
def __init__(self):
self.data = None
def Recur(self, nodeName, data):
if self[nodeName] is None:
self[nodeName] = data;
def Insert(self, data):
self.Recur("data", data)
__getitem__ = self.__getattr__
__setitem__ = self.__setattr__
NB: This code is untested
This allows Insert to choose the name ("data") to which Recur assigns a value. Recur, for its part, uses the dict-key get-item syntax of Python to assign a value to the key data in our quasi-dict object; however, we set the get-item and set-item semantics to be the same as the get-attribute and set-attribute semantics with the last two lines — this ensures that self["name"] means the same thing as self.name. A less mysterious implementation would be:
def __getitem__(self, key):
return self.__getattr__(key)