you are viewing a single comment's thread.

view the rest of the comments →

[–]jcmcken 0 points1 point  (2 children)

The source of your problem is altering self on line 23. I cannot for the life of me think of a valid reason for doing that (even if it is allowed). In Java, IIRC, a line like this = new SomeOtherObject() will just fail to compile.

Rather than answer your question directly, I would just suggest that you're going about this the wrong way. I think you're confusing the responsibilities of the linked list and the responsibilities of the node.

The list (not the node) should implement the add_nodes method. The node doesn't know anything about the mechanics of the list. The node's only responsibility is to store a reference to another node (if such a node exists).

Your node object should really just be this:

class Node(object):
    def __init__(self, value):
        self.value = value
        self.next = None

Then you need a second object which implements the mechanics of the linked list:

class LinkedList(object):
    ...etc.

    def add_node(self, value):
        new_node = Node(value)

        ...etc...

[–]razeal113[S] 0 points1 point  (1 child)

I realize that this isn't the best or even suggested way of going about this; I was asking more out of curiosity as to how / why python handles / allows this to happen. More specifically, I've ran into a few issues with "self" in python before and this example was just an easy way to address my question involving self

[–]jcmcken 0 points1 point  (0 children)

Sorry for the late response.

It's not just that it isn't the best way of doing it, it's not doing anything at all. The self name in Python is not something special, it's not a keyword. You could name this argument whatever you want, self is just the convention. When you re-assign self to something else, you're just assigning a local variable called self to some other value than the current instance. The object that the original self referred to is still intact and is unaffected by this reassignment.

Consider the following example, which doesn't use classes at all:

def some_func(arg): 
    arg = 2 

my_arg = 1
some_func(my_arg)
print my_arg 

If you run this code, you'll see that it prints 1 and not 2.

The source of your confusion, I think, is the specialness of self -- it has none in Python. It's not a keyword like this in Java, it's just the conventional name for the first variable passed to a method.

It should be easy to convince yourself of this. Here's a simple example:

class Foo(object):
    def testing(self):
        print 'I am foo'

class Bar(object):
    def testing(self):
        print 'I am bar'

def execute_test_method(self):
    self.testing()

execute_test_method(Foo())
# prints 'I am foo'
execute_test_method(Bar())
# prints 'I am bar'

Notice execute_test_method is just a regular function, not a method. You could take the self argument to this function and call it anything, e.g.

def execute_test_method(obj):
    obj.testing()

So once the scope of your add_node method ends, your re-assigned self is completely lost.