skip to Main Content

This is not working looks like “keys” function is broken… it lists everything in the class AND referenced classes. what am i doing wrong … the more i try python the more i am convinced its programmed by incompetents… same thing in php is a 2 min thing. :-/

class Nodes:
  nodes = {}
  def nd_add(self,nId):
    self.nodes[nId]= Node(nId)
  def nd_print(self):  
    for node in self.nodes.keys():
  #    print node
      self.nodes[node].nd_print()
  def keys(self):
    return self.nodes.keys()   


class Node:
  childs = Nodes()  
  ddid = False
  def __init__(self,nid):
    self.ddid = nid
  def nd_print(self):
    print self.ddid
    print self.childs.keys()
   # self.nodes.nd_print()      


root =  Nodes()
root.nd_add("bob")
root.nd_add("dub")
root.nodes["bob"].childs.nd_add("sponge")
print "root"
root.nd_print()

this is what comes out:

root
sponge
['sponge', 'bob', 'dub']
bob
['sponge', 'bob', 'dub']
dub
['sponge', 'bob', 'dub']

py version is 2.7

2

Answers


  1. You are confusing instance variables with class variables.

    Including a variable definition within the class definition, as you did above, introduces a class variables, this means, the variable does not belong to individual objects, but exists only once for the class.

    Consider this example:

    class MyClass:
        a = [5]                                                                                               
    
        def __init__(self):                                                                                   
            self.b = [10]                                                                                     
    
    ins1 = MyClass()                                                                                          
    ins2 = MyClass()                                                                                          
    print("ins1", ins1.a, ins1.b)                                                                             
    print("ins2", ins2.a, ins2.b)                                                                             
    ins1.a.append(6)                                                                                          
    ins1.b.append(11)                                                                                         
    print("ins1", ins1.a, ins1.b)                                                                             
    print("ins2", ins2.a, ins2.b) 
    

    Outputs:

    ins1 [5] [10]                                                                                             
    ins2 [5] [10]                                                                                             
    ins1 [5, 6] [10, 11]                                                                                      
    ins2 [5, 6] [10] 
    

    Notice how a changed for both, and b only changed for ins1.
    You can also do something like print(MyClass.a), because a belongs to MyClass, but not print(MyClass.b), because the class itself does not have an attribute b, only its instances do. This is not because Python was designed by incompetent programmers, it is because everything is an object in Python, including the class. (type(MyClass) returns class) Therefore, the class itself can have attributes, which are different from the attributes of its instances! The instances can access those variables with the .attribute syntax, but it is still only a reference to the class variable.

    Section 9.3.5 of the official tutorial explains this, and gives the exact same mistake as an example, as well as use cases for class variables.

    note: if you are new to python, you should probably stick to python 3, as 2 is not supported anymore. The differences are minor though.

    Login or Signup to reply.
    • From other answers instance variables and class variables should be clear
    • I have done some code modifications. You can use it as a reference

      class Nodes:
          def __init__(self):
              self.nodes = {}    # instance variable
          def nd_add(self,nId):
              self.nodes[nId]= Node(nId)
          def nd_print(self, parent=None):
              for node in self.nodes.keys():
                  #    print node
                  self.nodes[node].nd_print(parent)
          def keys(self):
              return self.nodes.keys()
      
      class Node:
          ddid = False
          def __init__(self,nid):
              self.ddid = nid
              self.childs = None      # instance variable
          def nd_print(self, parent=None):
              if parent is None:
                  print '%s is a parent Node: '%self.ddid
              else:
                  print '%s is a child node of %s'%(self.ddid, parent)
              if self.childs is not None:
                  self.childs.nd_print(self.ddid)
          def nd_add_child(self, child_id):
              self.childs = Nodes()
              self.childs.nd_add(child_id)
      
      root =  Nodes()
      root.nd_add("bob")
      root.nd_add("dub")
      root.nodes["bob"].nd_add_child("sponge")
      root.nodes['bob'].childs.nodes['sponge'].nd_add_child('xxx') # this needs a proper function
      print "root"
      root.nd_print()
      
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search