473,387 Members | 1,517 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

sharing dictionaries amongst class instances

Hi,
Really hung up on this one. I'm trying to get all the fields of a
dictionary to be unique for each class:

class A {
my_dict = []
dict_entry = { 'key1':0, 'key2':0 }

__init__(self):
for x in range(10):
tmp = copy.deepcopy(self.dict_entry)
tmp['key1'] = x
self.my_dict.append(tmp)
}

in a driver, I have

inst0, inst1 = A.A(), A.A()
inst0.my_dict[1]['key2'] = "ted"
inst1.my_dict[5]['key2'] = "steve"
inst0.display()
inst1.display()

printing them out shows that both objects have ted and steve in their
dictionaries. I have done this very thing outside of a class, and it works
wonderfully. All other attributes in the class are able to remain unique.
ie, inst0.data = 5 and inst1.data = 8 works fine.
I believe I could set the dictionaries up beforehand, but they will be
substatially different sizes, and it certainly wouldn't be proper.

Any ideas? Thanks very much for any insight.

Jul 18 '05 #1
7 2174
Kerry Neilson wrote:
Hi,
Really hung up on this one. I'm trying to get all the fields of a
dictionary to be unique for each class:

class A {
my_dict = []
dict_entry = { 'key1':0, 'key2':0 }

__init__(self):
for x in range(10):
tmp = copy.deepcopy(self.dict_entry)
tmp['key1'] = x
self.my_dict.append(tmp)
}


class A { ... } is *not* Python. Are you converting from Java :-) ?
From what follows, I conclude that you want the dicitonary to be unique for
each *instance* (if you want it unique for the class, you are already
there). Unlike Java, you must put it in the constructor then (untested):

class A:
def __init__(self):
self.my_dict = {"key1": 0, "key2": 0}

Dictionaries are the {} thingies, [] indicate list literals. Deepcopy should
be buried very deep in the documentation, where no newbie will ever find
it...
Seriously, take the time to read the excellent tutorial that comes with
Python, and only then try to clean up this mess.

Peter

Jul 18 '05 #2
On Sunday 09 Nov 2003 8:22 pm, Kerry Neilson wrote:
Hi,
Really hung up on this one. I'm trying to get all the fields of a
dictionary to be unique for each class:

class A {
my_dict = []
dict_entry = { 'key1':0, 'key2':0 }

__init__(self):
for x in range(10):
tmp = copy.deepcopy(self.dict_entry)
tmp['key1'] = x
self.my_dict.append(tmp)
}

in a driver, I have

inst0, inst1 = A.A(), A.A()
inst0.my_dict[1]['key2'] = "ted"
inst1.my_dict[5]['key2'] = "steve"
inst0.display()
inst1.display()

printing them out shows that both objects have ted and steve in their
dictionaries. I have done this very thing outside of a class, and it works
wonderfully. All other attributes in the class are able to remain unique.
ie, inst0.data = 5 and inst1.data = 8 works fine.
I believe I could set the dictionaries up beforehand, but they will be
substatially different sizes, and it certainly wouldn't be proper.

Any ideas? Thanks very much for any insight.


Kerry,

two observations:

1) That's not proper Python! ;-) and 2) I think the behaviours you want are
only available in 'new style' classes, i.e. classes based upon 'object'. Did
you mean:

---8<---
class A(object):
my_dict = []
dict_entry = { 'key1':0, 'key2':0 }

def __init__(self):
for x in range(10):
tmp = copy.deepcopy(self.dict_entry)
tmp['key1'] = x
self.my_dict.append(tmp)
---8<---

A.my_dict is a /class variable/, i.e. it is tied to the class, not the
instance - there's only one of them, viz:

---8<---
inst0,inst1=A(),A()
id(inst0),id(inst1) # get the id of the instances: (1083256236, 1083254732) id(inst0.my_dict),id(inst1.my_dict) # and the id of their my_dict lists: (1083253228, 1083253228) inst0.my_dict is inst1.my_dict True

---8<---

If you move the initial assignment of my_dict into the __init__() procedure,
and call it self.my_dict() instead, then you'll get a new instance of a list
each time - maybe this is what you want. BTW, is there any particular reason
for choosing the word 'my_dict' to describe a list?

hope this helps you arrive at a solution ;-)

-andyj
Jul 18 '05 #3
> class A { ... } is *not* Python. Are you converting from Java :-) ?
From what follows, I conclude that you want the dicitonary to be unique for each *instance* (if you want it unique for the class, you are already
there). Unlike Java, you must put it in the constructor then (untested):

class A:
def __init__(self):
self.my_dict = {"key1": 0, "key2": 0}

Dictionaries are the {} thingies, [] indicate list literals. Deepcopy should be buried very deep in the documentation, where no newbie will ever find
it...
Seriously, take the time to read the excellent tutorial that comes with
Python, and only then try to clean up this mess.

hmm ... I didnt' word this quite right. I want a list [] of dictionaries
{}. I mean for it to be similar to an array of structs in C, only using a
dictionary instead of a struct and a list instead of an array. Seem
reasonable?

I have read the entire tutorial as well as "Learning Python" in its utter
entirety. This is precisely how I know of deepcopy. I noticed that when I
appended dictionaries to my list, modifying one modifed them all. I want
each entry to be unique. I don't see how to do this without deepcopy. What
really confuses me is that this same scenario works when not embedded in a
class.

As for your suggestion, putting the dictionary initialization and the list
in the contructor did the trick. I had this:

class a:
x = 0
y = 0
:

I suppose it's a c++ leftover thing, thinking i had to declare before I
init. I don't yet understand why it's different for a simple data type than
it is for the list of dictionaries. But by taking the dict_entry{} and
my_dict[] out of the top of the class, it works without deepcopy. Thanks
for the help.
Jul 18 '05 #4


Kerry,

two observations:

1) That's not proper Python! ;-) and 2) I think the behaviours you want are
only available in 'new style' classes, i.e. classes based upon 'object'. Did
you mean:

---8<---
class A(object):
my_dict = []
dict_entry = { 'key1':0, 'key2':0 }

def __init__(self):
for x in range(10):
tmp = copy.deepcopy(self.dict_entry)
tmp['key1'] = x
self.my_dict.append(tmp)
---8<---

A.my_dict is a /class variable/, i.e. it is tied to the class, not the
instance - there's only one of them, viz:

---8<---
inst0,inst1=A(),A()
id(inst0),id(inst1) # get the id of the instances: (1083256236, 1083254732) id(inst0.my_dict),id(inst1.my_dict) # and the id of their my_dict lists: (1083253228, 1083253228) inst0.my_dict is inst1.my_dict True

---8<---

If you move the initial assignment of my_dict into the __init__() procedure,
and call it self.my_dict() instead, then you'll get a new instance of a list
each time - maybe this is what you want. BTW, is there any particular
reason
for choosing the word 'my_dict' to describe a list?

hope this helps you arrive at a solution ;-)

Thanks for the reply, Andy.
Your observation was correct, as I also learned from Peter, and moving the
initial assignment into __init__ is whta I wanted. I guess I didn't realize
that one could do that, being more familiar with c++. And no, calling a
list my_dict was pure accident. Perhaps my explanation in response to Peter
explains it a bit better.

Thanks.
Jul 18 '05 #5

"Kerry Neilson" <km******@REMOVEyahoo.com> wrote in message
news:gmxrb.114011$275.322447@attbi_s53...
Hi,
Really hung up on this one. I'm trying to get all the fields of a
dictionary to be unique for each class:

class A {
my_dict = []
dict_entry = { 'key1':0, 'key2':0 }

__init__(self):
for x in range(10):
tmp = copy.deepcopy(self.dict_entry)
tmp['key1'] = x
self.my_dict.append(tmp)
}
I don't really understand what you're trying to do here, and it doesn't help
that the syntax is completely wrong. Try pasting directly from real code or
an interactive session in the future, and not trying to ad-lib an email
message.

I assume you mean this (watch me break my own advice):

import copy
class A:
dictlist = []
dictlist_elem = { 'key1':0, 'key2':0 }

def __init__(self):
for x in range(10):
tmp = copy.deepcopy(self.dictlist_elem)
tmp['key1'] = x
self.dictlist.append(tmp)
Now, this code makes no sense to me without knowing what you want to do.
Init will just keep adding similar dictionaries to dictlist, which are
accessable from all instances.
a = A()
[ D['key1'] for D in a.dictlist] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] b = A()
[ D['key1'] for D in a.dictlist] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [ D['key2'] for D in a.dictlist] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Is this what you want?
in a driver, I have

inst0, inst1 = A.A(), A.A()
inst0.my_dict[1]['key2'] = "ted"
inst1.my_dict[5]['key2'] = "steve"
inst0.display()
inst1.display()
So, class A is now in a module named A? And what does A.A.display()
display? (You didn't include code for that method).

I'll assume that the module detail is insignificant, and that display()
prints dictlist.
printing them out shows that both objects have ted and steve in their
dictionaries.
Well, yes. You declared your dictionary and dictionary lists as class
attributes. Each instance does a lookup in itself, and not finding
'dictlist' it looks in the class, where it's found.

Ok, this point can often trip people up, so I'll go into more detail. (The
following is for "classic" classes, which are on their way out. New-style
classes are a bit different wrt instantiation and type.)

In Python, classes are objects. So when you define class C, what you're
saying is "make a class object which has these attributes and these methods,
and make the name 'C' point to that object."
class C: .... someint = 12
.... mylist = [1,2,3]
.... C <class __main__.C at 0x00AC5600> C.someint 12 C.mylist [1, 2, 3]
See? It's a real object with a real location in memory, not just a
"template" for "real" instances. Classes are just as real as instances.

When you make an instance, Python makes a new object (an instance) and then
calls C.__init__(newinstanceobject). Init is an instance
configurator--anything done in init is only done in the instance, not in the
class.

Indeed, all instances use the class's methods. instanceobject.dosomething()
is really C.dosomething(instanceobject) (where C is determined at runtime,
as the derived class which provides the method in question, after
inheritence is taken into consideration). The "self" you add to each method
object is the stand-in argument which will be the instance itself.

Now, if you don't keep the above in mind, behavior like this becomes
shocking:
myinst = C()
myinst2 = C()
myinst.someint

12 myinst.someint = 0
myinst.someint 0 myinst2.someint #Ints work... 12 myinst2.mylist.append(5)
myinst2.mylist [1, 2, 3, 5] myinst.mylist #What the?! [1, 2, 3, 5] C.mylist #Huh?

[1, 2, 3, 5]

When you do assignment on an instance, you are adding an attribute *to the
instance*, not looking up that attribute in the instance/class hiearchy.
But when you *modify* an attribute, Python *does* look for that attribute,
does find it in the class object, and does modify it in the class object,
*not* in the instance object!

Assignment is fundamentally different from modification. Assignment makes a
name point to an object. mylist[2] = 'something' makes the third item in
mylist (an un-named name, if you will) point to 'something'. But
mylist.dosomething() is radically different! It changes the object *in
place*. Just to make a point of how different it is, any in-place
object-modifying method will return None.
I have done this very thing outside of a class, and it works
wonderfully.
I don't really know what this would look like outside of a class; I'm not
really sure what "outside of a class" means.
All other attributes in the class are able to remain unique.
ie, inst0.data = 5 and inst1.data = 8 works fine.
Why this happens should make sense now.
I believe I could set the dictionaries up beforehand, but they will be
substatially different sizes, and it certainly wouldn't be proper.

Any ideas? Thanks very much for any insight.


If only the subject of this message were the question, I would answer: "Just
declare the dictionary in the class object of the instances." However, I
suspect that the question in your mind means a thing different from what it
means to Python, and that you will need to reclarify your problem.

--
Francis Avila

Jul 18 '05 #6
> See? The old value seems to reappear. When you say a.x and there is no
instance attribute, Python looks up the class attribute with the same name. So you can use the class attribute as a kind of default value for the
instance attribute.
But beware, this technique bites you as soon as you try it with mutables:
a.y["key"] = "value"
This looks the same, whether y is an instance or class attribute, and you
would not complicate client code with some detection scheme.
A.y {'key': 'value'}

Oops, there was no y attribute in the instance, so we inadvertently

changed y of the underlying class.


Thank you. Your message really cleared a lot of things up for me.
Jul 18 '05 #7
On Sun, 09 Nov 2003 20:22:36 GMT, "Kerry Neilson" <km******@REMOVEyahoo.com> wrote:
Hi,
Really hung up on this one. I'm trying to get all the fields of a
dictionary to be unique for each class:
Please post something that at least compiles
class A {

File "<stdin>", line 1
class A {
^
SyntaxError: invalid syntax

class A { ^--this must be left over from some abortive experiment my_dict = []
dict_entry = { 'key1':0, 'key2':0 }

__init__(self):
for x in range(10):
tmp = copy.deepcopy(self.dict_entry)
tmp['key1'] = x
self.my_dict.append(tmp)
}

in a driver, I have

inst0, inst1 = A.A(), A.A() This looks like you are not showing an import A, assuming that class A is defined in A.py
inst0.my_dict[1]['key2'] = "ted"
inst1.my_dict[5]['key2'] = "steve"
inst0.display()
inst1.display()

printing them out shows that both objects have ted and steve in their I suggest you copy and paste from the session where you did that. Otherwise
you're wasting your time and everyone else's.
dictionaries. I have done this very thing outside of a class, and it works
wonderfully. All other attributes in the class are able to remain unique. The above doesn't work period, so there is no telling what you actually did,
and I might be able to guess what you are trying to do, but I don't really want to, sorry.
ie, inst0.data = 5 and inst1.data = 8 works fine.
I believe I could set the dictionaries up beforehand, but they will be
substatially different sizes, and it certainly wouldn't be proper.

Any ideas? Thanks very much for any insight.

See above, guess I need a snack ;-)

Regards,
Bengt Richter
Jul 18 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: amit.bhatia | last post by:
Hi, I have also posted this to the moderated group. I have 2 classes A and B, what does the following mean in header file for class A: class A { class B &b; .... };
5
by: Tinius | last post by:
I have created a class which I wish to reuse amongst several projects. But each time I Add the class to a new project, it creates a copy of that class in the folder of the new project. This means...
3
by: Dax | last post by:
//////////////// Inside the APPLICATION/ game //how do i get the same instance running in the //dll into my app? i.e the pointer ferrari //does not work ! it creates a new instance in the ...
5
by: oliv | last post by:
Hi, New to .NET, I was wondering what was the proper way to share a variable between all the instances of a web page. I try with a static var, but it does not seem to always work. Why is that ? ...
5
by: brainstaurm | last post by:
I am trying to make some of the in-memory dictionaries in my code persistent using bsddb 4.3. Here is an example dictionary in my code for which I would like to create a persistent version: #...
23
by: special_dragonfly | last post by:
Hello, I'm new to this group, I've read through the subject of a lot of the group but can't find anything relevant. Perhaps my question is too basic but I'm still stuck. Classes and Dictionaries....
19
by: Zytan | last post by:
I want multiple instances of the same .exe to run and share the same data. I know they all can access the same file at the same time, no problem, but I'd like to have this data in RAM, which they...
45
by: =?Utf-8?B?QmV0aA==?= | last post by:
Hello. I'm trying to find another way to share an instance of an object with other classes. I started by passing the instance to the other class's constructor, like this: Friend Class...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.