#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    80
    Rep Power
    2

    Object Instatiation Issue. I think.


    Okay, so I have an object structure that is as follows:

    "Card", the container object-
    ---Node_Container, a dict object initialized when Card is created.
    ------Composite(node,list) that is added afterwards.

    For some reason, whenever I instantiate two cards, each has a different Node_Container, but both seem to contain the same composite node. Whenever I make changes to one, it makes changes to the other.

    The code's kind of awkward due to some placeholders, but here's what I have so far:

    Code:
    raw_list=['PYR','CP']
    
    class node_container(dict):
    	pass
    
    class card():
    	name=str()
    	nodes=node_container()
    	def __repr__(self):
    		return self.name
    
    class node():
    	pass
    
    class pouch(dict):
    	def __init__(self):
    		for item in raw_list:
    			self[item] = 0
    
    class composite(node,list):
    	def parse(self):
    		raw_val = pouch()
    		compos = list(self)
    		while len(compos) > 0:
    			nxt=compos.pop(0)
    			print nxt
    			item,amt = nxt[0],nxt[1]
    			if item in raw_list:
    				raw_val[item] += amt
    			if item in index.keys():
    				ref = index[item]
    				compos += ref.nodes['comp']
    		return raw_val
    
    master_folio,index=list(),dict()
    
    def new_card(indval,cname):
    	new = card()
    	master_folio.append(new)
    	new.name = cname
    	index[indval] = new
    	return new
    
    wk = new_card('STN-POW-001','Strike I')
    wk.nodes['comp']=composite([['PYR',20],['CP',10]])
    
    wk = new_card('STN-POW-002','Strike II')
    wk.nodes['comp']=composite([['CP',20],['PYR',15],['STN-POW-001',1]])
    And, running it in IDLE, here is an example of the error:
    Code:
    >>> index
    {'STN-POW-001': Strike I, 'STN-POW-002': Strike II}
    
    Okay, so I know the index does contain two separate cards... 
    
    >>> master_folio
    [Strike I, Strike II]
    
    Likewise, each instance seems to have been instantiated correctly with new_card(). 
    
    >>> index['STN-POW-002'].nodes['comp']
    [['CP', 20], ['PYR', 15], ['STN-POW-001', 1]]
    
    Okay, good. That should be the composite values for Strike II. 
    
    >>> index['STN-POW-001'].nodes['comp']
    [['CP', 20], ['PYR', 15], ['STN-POW-001', 1]]
    
    Okay, here's the problem. For some reason,  changing the composite for one in the main code changed the composite for the other. 
    
    >>> master_folio[0]==master_folio[1]
    False
    
    The objects ARE different. They just seem to copy off the nodes list. 
    
    >>> index['STN-POW-001'].nodes['comp'] = composite([['PYR',20],['CP',10]])
    >>> index['STN-POW-001'].nodes['comp']
    [['PYR', 20], ['CP', 10]]
    
    Okay. It's changed correctly. 
    
    >>> index['STN-POW-002'].nodes['comp']=composite([['CP',20],['PYR',15],['STN-POW-001',1]])
    >>> index['STN-POW-002'].nodes['comp']
    [['CP', 20], ['PYR', 15], ['STN-POW-001', 1]]
    
    Okay. Now we know this one is good too. 
    
    >>> index['STN-POW-001'].nodes['comp']
    [['CP', 20], ['PYR', 15], ['STN-POW-001', 1]]
    
    Why did this one change!? The two instances the dictionary refers to are separate.
    I hope that serves as adequate explanation.
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,966
    Rep Power
    481
    The issue concerns class attributes versus object attributes, I think. Altering your program slightly to show id(nodes) in several places you'll see that it's always the same, as it should be. Or I misunderstand your concern.
    Code:
    raw_list=['PYR','CP']
    
    class node_container(dict):  # dict
        pass
    
    class card():
        name=str()             # class instances name is ''
        nodes=node_container() # class instances nodes is a dict
        print('{}: id nodes'.format(id(nodes)))
        def __repr__(self):
            return self.name
    
    class node(): # a storage area
        pass
    
    class pouch(dict):  # dict with some items initialized to 0
    
        def __init__(self):  # raw_list=['PYR','CP']
            for item in raw_list:
                self[item] = 0
    
    class composite(node,list):
    
        def parse(self):
            raw_val = pouch()
            compos = list(self)
            while len(compos) > 0:
                nxt=compos.pop(0)
                print(nxt)
                item,amt = nxt[0],nxt[1]
                if item in raw_list:
                    raw_val[item] += amt
                if item in index.keys():
                    ref = index[item]
                    compos += ref.nodes['comp']
            return raw_val
    
    
    (master_folio,index,) = (list(),dict(),)
    
    def new_card(indval,cname):
        new = card()
        master_folio.append(new)
        new.name = cname
        index[indval] = new
        return new
    
    wk = new_card('STN-POW-001','Strike I')
    wk.nodes['comp']=composite([['PYR',20],['CP',10]])
    print('{}: id wk.nodes'.format(id(wk.nodes)))
    
    wk = new_card('STN-POW-002','Strike II')
    wk.nodes['comp']=composite([['CP',20],['PYR',15],['STN-POW-001',1]])
    print('{}: id wk.nodes'.format(id(wk.nodes)))
    
    print('''{}: id index['STN-POW-002'].nodes'''.format(id(index['STN-POW-002'].nodes)))
    print('''{}: id index['STN-POW-001'].nodes'''.format(id(index['STN-POW-001'].nodes)))

    Output:
    $ ( cd /tmp && python p.py )
    21736128: id nodes
    21736128: id wk.nodes
    21736128: id wk.nodes
    21736128: id index['STN-POW-002'].nodes
    21736128: id index['STN-POW-001'].nodes
    $
    $
    $
    $ ( cd /tmp && python3 p.py )
    19115088: id nodes
    19115088: id wk.nodes
    19115088: id wk.nodes
    19115088: id index['STN-POW-002'].nodes
    19115088: id index['STN-POW-001'].nodes
    $

    Code:
    class module_scope:
        class_scope = list()
        def __init__(self):
            self.object_scope = True
    
    def f():
        global global_scope
        local_scope = 'defined in f'
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    80
    Rep Power
    2
    Okay, yeah, the issue is it SHOULDN'T be doing that.

    When I call the card:
    Code:
    class card():
            name=str()
            nodes=node_container()
    From my understanding, since I put parenthesis after node_container, it instantiates a separate dictionary for each object (or, rather, it should). Just like it has it's own name, it should have it's own unique node container. That's what I need it to do; I'm using a dictionary instead of a list so that I can ensure that A. The nodes in the node container are a set, none of which are replicated and B. I can call them without explicitly knowing their order (like I call wk.nodes['comp'] all the time) Currently, only the composition node is present, but as you can see there are placeholders for more.

    So, is there a way to instantiate separate node_container() objects, one for each card?
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,966
    Rep Power
    481
    () following node_container cause the callable to be called. Create this file, and import it into python. It prints a message because the class runs all it's next-level block code on import.
    Code:
    class node_container(dict):
        pass
    
    class card():
        nodes=node_container() # this happens once, on import
        print('nodes: {}'.format(nodes))
    
        def __init__(self):
            self.nodes = node_container()  # local to the object.  This statement executes for each new card object object.
            print('__init__ executes, object local nodes is {}'.format(self.nodes))
    Last edited by b49P23TIvg; February 13th, 2013 at 06:43 PM.
    [code]Code tags[/code] are essential for python code and Makefiles!
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    80
    Rep Power
    2
    Okay, I think I get it now. Thank you very much.

IMN logo majestic logo threadwatch logo seochat tools logo