0

Learning Python and I ran into some problems when I was working on making a linked list class. This is just a quick node and dirty node class. In java I would of down private Node next and private int val but I only knew of global as the python cousin. How does this look?

#class Node class

class Node(object):
    global next
    global val
    def __init__(self):
        next
        val
    def setNext(self, aNext):
        self.next = aNext
    def getNext(self):
        return self.next
    def setVal(self, aVal):
        self.val = aVal
    def getVal(self):
        return self.val

Then I tried to use a Node in another class with

from Node import *
head = Node()

How ever I am getting an error of undefined variable. Sorry for the simple question just new to python. Appreciate the help.

6
  • 2
    You should read the Python tutorial to familiarize yourself with the basics of Python. Commented Sep 25, 2013 at 21:46
  • 1
    Like peter says, you don't need set/get-ters yet. If you do need to add logic, python uses @property-ies instead of getter/setters. docs.python.org/2/library/functions.html#property Commented Sep 25, 2013 at 21:48
  • Note that almost every time you think you want a linked list you actually don't, at least in Python. Try a deque, pair of lists, pair of deques, OrderedDict (with all the values equal to None) or so on. Commented Sep 25, 2013 at 21:51
  • 1
    Also, just writing next in the __init__ method doesn't do anything except look up the value of the global next variable and immediately forget it. Commented Sep 25, 2013 at 21:56
  • 1
    On second thought, it does no something. Because you haven't actually set a value for a global variable named next anywhere, it raises a NameError, which is exactly what you were complaining about… Commented Sep 25, 2013 at 22:00

4 Answers 4

7

I would implement this this way:

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

That's it. No getters or setters - Python doesn't use them. Instead, you refactor into a property if you need to move away from the basic attribute reference logic.

You can then create nodes with or without values or successors:

tailnode = Node()
tailnode.val = 'foo'
midnode = Node(val='bar')
midnode.next = tailnode
headnode = Node(val='baz', next=midnode)
Sign up to request clarification or add additional context in comments.

Comments

1

You don't need the "global val" / "global next" .. It's a mistake even. instead just write val = None next = None

and initiate them in the __init__()

Meaning, the first lines in your class should be like:

class Node(object):
    # You can choose whether to initialize the variables in the c'tor or using your setter methods
    def __init__(self, val=None, next=None):
        self.next = next
        self.val = val

1 Comment

Replacing the useless globals that you intend to shadow with instance attributes with useless class attributes that you intend to shadow with instance attributes isn't much of a step forward… (And if you were trying to "declare" the member variables to initialize them later, as you would in Java, that's not what you're doing, and thre is no way to do it, because you don't declare variables in Python.)
1

If you really want private variables in Python… then you don't want private variables, and should read Peter DeGlopper's answer.

If you still really, really want private variables in Python… well, you can't have them. But you can have "cooperatively private" variables—variables that nobody will find unless they go looking for them, and that won't clutter the screen when you introspect things in the interpreter, and so on, and, most importantly, that Python programmers know, by convention, that they aren't supposed to touch. All you have to do is start the name with an underscore.


However, your code isn't creating member variables at all, for a number of reasons.

First, global does not declare or define a variable; all it does is tell Python, "when you see this variable later, don't use the normal rules to figure out if it's local or global, always use the global copy". You still have to assign a value to the variable somewhere; otherwise, you'll get a NameError.

Next, variables that you assign in the class definition are class members—similar to Java's static members, although not identical. Each class member is shared by all instances of the class. That's not what you want here; each Node is supposed to have its own separate val and next, not share one with all other Nodes, right?

Normal instance member variables are always accessed through dot syntax—as self.foo from inside the class's methods, or as spam.foo from outside.

So, where do you declare those? You don't. Python doesn't declare anything. You can add new members to an object at any time. The usual way to create a standard set of instance members is in the __init__ method:

class Node(object):
    def __init__(self):
        self._next = None
        self._val = None
    def setNext(self, aNext):
        self._next = aNext
    def getNext(self):
        return self._next
    def setVal(self, aVal):
        self._val = aVal
    def getVal(self):
        return self._val

But really, you can just let the setters create them. That way, you'll catch the error if someone calls getNext without having called setNext first (which is, I assume, illegal).

class Node(object):
    def setNext(self, aNext):
        self._next = aNext
    def getNext(self):
        return self._next
    def setVal(self, aVal):
        self._val = aVal
    def getVal(self):
        return self._val

Or, alternatively, force the user to initialize the object with valid values at construction time:

    def __init__(self, next, val):
        self._next = next
        self._val = val

Again, there's no good reason to use setters and getters in the first place in Python.

So, the simplest implementation of your class is:

class Node(object):
    pass

While the most Pythonic is:

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

… which, you'll notice, is Peter DeGlopper's answer, which, as I said at the start, is probably what you want. :)

Comments

0

Python doesn't really use private variables.

Something like this would be best:

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

Then, you make and set the node like this:

>>> node = Node()
>>> node.val = 5
>>> node2 = Node()
>>> node2 = 1
>>> node.next = node2
>>> node.next.val
1

If you want to create node with Node(5, Node(1)), use:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.