Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > dictionary as attribute of a class...

Reply
Thread Tools

dictionary as attribute of a class...

 
 
tinauser
Guest
Posts: n/a
 
      01-05-2011
Hallo list,
here again I have a problem whose solution might be very obvious, but
I really cannot see it:
I have a class having as attribute a dictionary whose keys are names
and values are instance of another class.
This second class has in turn as an attribute a dictionary.
I want a function of the first class that can change value of one of
the second class instance's dictionary.
however I cannot do it without modifying this attribute for ALL the
instance of the second class contained in the first class' dictionary.
What I'm doing wrong?

the code:

###############
###can i change a dictionary attribute of an instantated object
without affectin all the instances of that object?

class mistClass():
def __init__(self,name,cDict={}):
print 'mistClass ',name,' Init'
self._name=name
self._cDict=cDict

def setName(self,n):
self._name=n

def getName(self):
return self._name

## def setDict(self,one,two):
## self._cDict['one']=one
## self._cDict['two']=two
def setDict(self,listK,listV):
assert len(listK)==len(listV)
for k,v in zip(listK,listV):
self._cDict[k]=v

def getDict(self):
return self._cDict

class mistClassContainer():
def __init__(self,name,dict_of_mistclass={}):
print 'init mistClassContainer ',name
self._name=name
self._DOM=dict_of_mistclass

def add_mistclass(self,mc):
for el in mc:
self._DOM[el]=mistClass(el)

## def mod_mistclasscDict(self,mc,one,two):
## self._DOM[mc].setDict(one,two)
def mod_mistclasscDict(self,mc,lK,lV):
self._DOM[mc].setDict(lK,lV)

a=mistClassContainer('firsmistclasscontainer')
a.add_mistclass(['mc1','mc2','mc3','mc4','mc5','mc6'])
print 'before modification'
for el in a._DOM.iterkeys():
print a._DOM[el].getDict()
print a._DOM[el].getName()

a.mod_mistclasscDict('mc1',['one','two'],['modone','modtwo'])
print 'after modification'
for el in a._DOM.iterkeys():
print a._DOM[el].getDict()
print a._DOM[el].getName()

b=mistClass('mc7')
print b.getDict()
print b.getName()
b.setName('modified name')
b.getName()

for el in a._DOM.iterkeys():
print a._DOM[el].getName()
 
Reply With Quote
 
 
 
 
Benjamin Kaplan
Guest
Posts: n/a
 
      01-05-2011
On Wed, Jan 5, 2011 at 10:07 AM, tinauser <(E-Mail Removed)> wrote:
> Hallo list,
> here again I have a problem whose solution might be very obvious, but
> I really cannot see it:
> I have a class having as attribute a dictionary whose keys are names
> and values are instance of another class.
> This second class has in turn as an attribute a dictionary.
> I want a function of the first class that can change value of one of
> the second class instance's dictionary.
> however I cannot do it without modifying this attribute for ALL the
> instance of the second class contained in the first class' dictionary.
> What I'm doing wrong?
>


This is one of the biggest gotchas in Python. Default arguments are
only evaluated *once*, when the function/method is declared. Not every
time the function is called. Every instance of mistClass that didn't
specify a separate cDict gets the same object as its cDict. The
solution is to use a sentinel value (either None or a single object
and use an "is" comparison) and create a new dict in the constructor
if the default argument is still the sentinel.

> class mistClass():
> * *def __init__(self,name,cDict={}):
> * * * *print 'mistClass ',name,' Init'
> * * * *self._name=name
> * * * *self._cDict=cDict
>


should be changed to

sentinel = object()
class mistClass :
def __init__(self, name, cDict=sentinel) :
print 'mistClass ',name,' Init'
self._name=name
if cDict is not sentinel :
self._cDict=cDict
else :
self._cDict = {}


> class mistClassContainer():
> * *def __init__(self,name,dict_of_mistclass={}):
> * * * *print 'init mistClassContainer ',name
> * * * *self._name=name
> * * * *self._DOM=dict_of_mistclass
>


and do the same thing with this one.
 
Reply With Quote
 
 
 
 
Peter Otten
Guest
Posts: n/a
 
      01-05-2011
tinauser wrote:

> Hallo list,
> here again I have a problem whose solution might be very obvious, but
> I really cannot see it:
> I have a class having as attribute a dictionary whose keys are names
> and values are instance of another class.
> This second class has in turn as an attribute a dictionary.
> I want a function of the first class that can change value of one of
> the second class instance's dictionary.
> however I cannot do it without modifying this attribute for ALL the
> instance of the second class contained in the first class' dictionary.
> What I'm doing wrong?
>
> the code:
>
> ###############
> ###can i change a dictionary attribute of an instantated object
> without affectin all the instances of that object?
>
> class mistClass():
> def __init__(self,name,cDict={}):


When you don't provide a cDict argument the default is used which is the
same for every instance. Change the above to

def __init__(self, name, cDict=None):
if cDict is None:
cDict = {}

> class mistClassContainer():
> def __init__(self,name,dict_of_mistclass={}):


Same here.

> def setName(self,n):
> self._name=n
>
> def getName(self):
> return self._name


Python has properties, so you don't need this just-in-case getter/setter
nonsense.

> for k,v in zip(listK,listV):
> self._cDict[k]=v


Make that

self._cDict.update(zip(listK, listV))

By the way, not everyone loves Hungarian notation...

 
Reply With Quote
 
tinauser
Guest
Posts: n/a
 
      01-05-2011
On Jan 5, 4:34*pm, Peter Otten <(E-Mail Removed)> wrote:
> tinauser wrote:
> > Hallo list,
> > here again I have a problem whose solution might be very obvious, but
> > I really cannot see it:
> > I have a class having as attribute a dictionary whose keys are names
> > and values are instance of another class.
> > This second class has in turn as an attribute a dictionary.
> > I want a function of the first class that can change value of one of
> > the second class instance's dictionary.
> > however I cannot do it without modifying this attribute for ALL the
> > instance of the second class contained in the first class' dictionary.
> > What I'm doing wrong?

>
> > the code:

>
> > ###############
> > ###can i change a dictionary attribute of an instantated object
> > without affectin all the instances of that object?

>
> > class mistClass():
> > * * def __init__(self,name,cDict={}):

>
> When you don't provide a cDict argument the default is used which is the
> same for every instance. Change the above to
>
> def __init__(self, name, cDict=None):
> * * if cDict is None:
> * * * * cDict = {}
>
> > class mistClassContainer():
> > * * def __init__(self,name,dict_of_mistclass={}):

>
> Same here.
>
> > * * def setName(self,n):
> > * * * * self._name=n

>
> > * * def getName(self):
> > * * * * return self._name

>
> Python has properties, so you don't need this just-in-case getter/setter
> nonsense.
>
> > * * * * for k,v in zip(listK,listV):
> > * * * * * * self._cDict[k]=v

>
> Make that
>
> self._cDict.update(zip(listK, listV))
>
> By the way, not everyone loves Hungarian notation...


Thanks both for the reply, I'll take some time to digest so to avoid
further error in the future.Thanks again.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Performance ordered dictionary vs normal dictionary Navkirat Singh Python 6 07-29-2010 10:18 AM
Re: Performance ordered dictionary vs normal dictionary Chris Rebert Python 0 07-29-2010 06:11 AM
creating a dictionary from a dictionary with regex james_027 Python 1 08-22-2007 07:39 AM
[DICTIONARY] - Copy dictionary entries to attributes Ilias Lazaridis Python 6 02-21-2006 11:27 AM
dictionary within dictionary Fox ASP General 5 03-13-2005 05:03 AM



Advertisments