The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages
> Python Programming
|
Object Instatiation Issue. I think.
Discuss Object Instatiation Issue. I think. in the Python Programming forum on Dev Shed. Object Instatiation Issue. I think. Python Programming forum discussing coding techniques, tips and tricks, and Zope related information. Python was designed from the ground up to be a completely object-oriented programming language.
|
|
 |
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

February 13th, 2013, 12:57 PM
|
|
Contributing User
|
|
Join Date: Dec 2012
Posts: 32
Time spent in forums: 1 h 53 m 20 sec
Reputation Power: 1
|
|
|
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.
|

February 13th, 2013, 04:05 PM
|
 |
Contributing User
|
|
|
|
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!
|

February 13th, 2013, 05:01 PM
|
|
Contributing User
|
|
Join Date: Dec 2012
Posts: 32
Time spent in forums: 1 h 53 m 20 sec
Reputation Power: 1
|
|
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?
|

February 13th, 2013, 05:41 PM
|
 |
Contributing User
|
|
|
|
() 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 05:43 PM.
|

February 13th, 2013, 06:56 PM
|
|
Contributing User
|
|
Join Date: Dec 2012
Posts: 32
Time spent in forums: 1 h 53 m 20 sec
Reputation Power: 1
|
|
Okay, I think I get it now. Thank you very much. 
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|