473,545 Members | 2,095 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How can I make a dictionary that marks itself when it's modified?

It's important that I can read the contents of the dict without
flagging it as modified, but I want it to set the flag the moment I add
a new element or alter an existing one (the values in the dict are
mutable), this is what makes it difficult. Because the values are
mutable I don't think you can tell the difference between a read and a
write without making some sort of wrapper around them.

Still, I'd love to hear how you guys would do it.

Thanks,
-Sandra

Jan 12 '06 #1
12 1519
sa***********@y ahoo.com wrote:
It's important that I can read the contents of the dict without
flagging it as modified, but I want it to set the flag the moment I add
a new element or alter an existing one (the values in the dict are
mutable), this is what makes it difficult. Because the values are
mutable I don't think you can tell the difference between a read and a
write without making some sort of wrapper around them.

Still, I'd love to hear how you guys would do it.


if the dictionary is small and speed not important, you can wrap it
in a class catching __getitem__ and __setitem__ and testing
if repr(self) changes.
--
-----------------------------------------------------------
| Radovan GarabĂ*k http://kassiopeia.juls.savba.sk/~garabik/ |
| __..--^^^--..__ garabik @ kassiopeia.juls .savba.sk |
-----------------------------------------------------------
Antivirus alert: file .signature infected by signature virus.
Hi! I'm a signature virus! Copy me into your signature file to help me spread!
Jan 12 '06 #2
ga************* *****@kassiopei a.juls.savba.sk wrote:
sa***********@y ahoo.com wrote:
It's important that I can read the contents of the dict without
flagging it as modified, but I want it to set the flag the moment I add
a new element or alter an existing one (the values in the dict are
mutable), this is what makes it difficult. Because the values are
mutable I don't think you can tell the difference between a read and a
write without making some sort of wrapper around them.

Still, I'd love to hear how you guys would do it.

if the dictionary is small and speed not important, you can wrap it
in a class catching __getitem__ and __setitem__ and testing
if repr(self) changes.

d = {1: [a, b],
2: [b, c]}

d[1][0] = 3

How would this work? __getitem__() will be called once, to get a
reference to the list, and so there's no opportunity to compare the
'before' and 'after' repr() values.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Jan 12 '06 #3
sa***********@y ahoo.com wrote:
It's important that I can read the contents of the dict without
flagging it as modified, but I want it to set the flag the moment I add
a new element or alter an existing one (the values in the dict are
mutable), this is what makes it difficult. Because the values are
mutable I don't think you can tell the difference between a read and a
write without making some sort of wrapper around them.

Still, I'd love to hear how you guys would do it.

Thanks,
-Sandra


Sandra

You appear to want:

D = {"a":obj1, "b":obj2}

when obj1 or obj2 changes, to notify D

I think that's hard to do in the general case (i.e., for any value of obj). You
will have to design/modify obj1 and obj2 or wrap them it to achieve this. If
the objects are not homogeneous, I'd give up ;-)

If you can design obj for the purpose it shouldn't be do hard, using the
observer pattern:

Here's a sketch:

class Observable(obje ct):
"""An object that notifies observers when it is changed"""
def __init__(self):
self._observers = []
def add_observer(se lf, observer):
self._observers .append(observe r)
def _notify(self, attrname, newval):
for observer in self._observers :
observer.notify (self, attrname, newval)
def __setattr__(sel f, attrname, val):
object.__setatt r__(self, attrname, val)
self._notify(at trname, val)

class DictObserver(di ct):
"""A dict that observes Observable instances"""
def __setitem__(sel f, key, value):
assert isinstance(valu e, Observable)
dict.__setitem_ _(self, key, value)
value.add_obser ver(self)
def notify(self, obj, attr, newval):
print "%s.%s = %s" % (obj, attr, newval)
a = Observable()
b = Observable()
D = DictObserver()
D["a"] = a
D["b"] = b
a.new_attribute = 4 <observer_dict. Observable object at 0x01AE9210>.new _attribute = 4 b.new_attribute = 6 <observer_dict. Observable object at 0x01AE98F0>.new _attribute = 6 a.new_attribute = 5 <observer_dict. Observable object at 0x01AE9210>.new _attribute = 5

Michael

Jan 12 '06 #4
On Thu, 12 Jan 2006 18:28:54 +0000, Steve Holden <st***@holdenwe b.com> wrote:
ga************ ******@kassiope ia.juls.savba.s k wrote:
sa***********@y ahoo.com wrote:
It's important that I can read the contents of the dict without
flagging it as modified, but I want it to set the flag the moment I add
a new element or alter an existing one (the values in the dict are
mutable), this is what makes it difficult. Because the values are
mutable I don't think you can tell the difference between a read and a
write without making some sort of wrapper around them.

Still, I'd love to hear how you guys would do it.

if the dictionary is small and speed not important, you can wrap it
in a class catching __getitem__ and __setitem__ and testing
if repr(self) changes.

d = {1: [a, b],
2: [b, c]}

d[1][0] = 3

How would this work? __getitem__() will be called once, to get a
reference to the list, and so there's no opportunity to compare the
'before' and 'after' repr() values.

You are right, but OTOH the OP speaks of a "flagging" the dict as modified.
If she made e.g., "modified" a property of the dict subclass, then
retrieving the the "modified" "flag" could dynamically check current state repr
vs some prior state repr. Then the question becomes "modified w.r.t. what prior state?"

This lets the OP ask at any time whether the dict is/has_been modified, but it's not a basis
for e.g., a modification-event callback registry or such.

Regards,
Bengt Richter
Jan 12 '06 #5
Steve Holden wrote:
ga************* *****@kassiopei a.juls.savba.sk wrote:
sa***********@y ahoo.com wrote:
It's important that I can read the contents of the dict without
flagging it as modified, but I want it to set the flag the moment I add
a new element or alter an existing one (the values in the dict are
mutable), this is what makes it difficult. Because the values are
mutable I don't think you can tell the difference between a read and a
write without making some sort of wrapper around them.

Still, I'd love to hear how you guys would do it.
if the dictionary is small and speed not important, you can wrap it
in a class catching __getitem__ and __setitem__ and testing
if repr(self) changes.


IMHO, that's too much.
d = {1: [a, b],
2: [b, c]}

d[1][0] = 3

How would this work? __getitem__() will be called once, to get a
reference to the list, and so there's no opportunity to compare the
'before' and 'after' repr() values.


I think tracking whether a dict gets modified should in fact only
trace changes to the dict, not to elements contained in the dict.
So __repr__ is probably too much, and also not the intent.

I'd just overwrite __setitem__ for write access to the dict.
Enforcing tracking of all contents is hard (as you showed above)
and probably not really needed.

If further tracking is reasonable, then one would continue and
patch contained lists as well.

my 0.2 € - chris

--
Christian Tismer :^) <mailto:ti****@ stackless.com>
tismerysoft GmbH : Have a break! Take a ride on Python's
Johannes-Niemeyer-Weg 9A : *Starship* http://starship.python.net/
14109 Berlin : PGP key -> http://wwwkeys.pgp.net/
work +49 30 802 86 56 mobile +49 173 24 18 776 fax +49 30 80 90 57 05
PGP 0x57F3BF04 9064 F4E1 D754 C2FF 1619 305B C09C 5A3B 57F3 BF04
whom do you want to sponsor today? http://www.stackless.com/
Jan 12 '06 #6
Just to add a word that I forgot:

Adhering to the subject line, the intent is to track modifications
of a dict.
By definition, modification of a member of a dict without replacing
the value is not considered a dict change.

I'd stick with the shallow approach.
Asking to track mutation of an element in the general case
is causing much trouble.
Support for element tracking can probably provided by overriding
the dict's getattr and recording the element in some extra
candidate list.
If the element itself is modified, it then could be looked up
as a member of that dict, given that the element's setattr
is traced, too.

ciao - chris

--
Christian Tismer :^) <mailto:ti****@ stackless.com>
tismerysoft GmbH : Have a break! Take a ride on Python's
Johannes-Niemeyer-Weg 9A : *Starship* http://starship.python.net/
14109 Berlin : PGP key -> http://wwwkeys.pgp.net/
work +49 30 802 86 56 mobile +49 173 24 18 776 fax +49 30 80 90 57 05
PGP 0x57F3BF04 9064 F4E1 D754 C2FF 1619 305B C09C 5A3B 57F3 BF04
whom do you want to sponsor today? http://www.stackless.com/
Jan 12 '06 #7
Christian Tismer wrote:
Just to add a word that I forgot:

Adhering to the subject line, the intent is to track modifications
of a dict.
By definition, modification of a member of a dict without replacing
the value is not considered a dict change.
Well, I agree. But I suppose much depends on exactly what the OP meant
by "... add a new element or alter an existing one". The post did follow
that with "(the values in the dict are mutable)", which is presumably
why garabik-2500 proposed catching __getitem__ as well as __setitem__.

I merely wanted to point out (not to you!) that there was no effective
way to capture a change to a mutable item without, as you say, modifying
the element classes.
I'd stick with the shallow approach.
Asking to track mutation of an element in the general case
is causing much trouble.
Support for element tracking can probably provided by overriding
the dict's getattr and recording the element in some extra
candidate list.
If the element itself is modified, it then could be looked up
as a member of that dict, given that the element's setattr
is traced, too.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Jan 13 '06 #8
Thanks to everyone who posted comments or put some thought into this
problem.

I should have been more specific with what I want to do, from your
comments the general case of this problem, while I hate to say
impossible, is way more trouble than it's worth.

By modified I meant that the dictionary has been changed from its
original (constructed) state by either:
1) A new element was added
2) An existing element was changed

I want to wrap a dictionary of cookies in mod_python. Cookies are
represented as objects with no methods. In light of this and Michael's
excellent post, I came up with the following code.

class CookieCollectio n(dict):
def __init__(self, d):
for k, v in d:
v.__setattr__ = self.__wrap_set attr(v.__setatt r__)
self[k] = v

self.modified = False

def __setitem__(sel f, key, value):
super(dict, self).__setitem __(key, value)
self.modified = True # we don't have to wrap this item, the dict
is modified, and can't ever be unmodified

def __wrap_setattr( self, real_setattr):
def setattr(attrnam e, val):
self.modified = True
real_setattr(at trname, val)
return setattr

def send(self, req):
if self.modified:
for cookie in req.cookies.val ues():
Cookie.add_cook ie(req, cookie)

The purpose of which is to be able to store any cookies sent with the
request in the CookieCollectio n, and then automatically call send()
before the headers are finished being sent and it will only do
something if the cookies have been altered (otheriwse they don't need
to be sent again.) I haven't tested the code yet, but the general idea
should be correct at the very least I think.

Thanks again,
-Sandra

Jan 13 '06 #9
Steve Holden wrote:
Christian Tismer wrote:
Just to add a word that I forgot:

Adhering to the subject line, the intent is to track modifications
of a dict.
By definition, modification of a member of a dict without replacing
the value is not considered a dict change.
Well, I agree. But I suppose much depends on exactly what the OP meant
by "... add a new element or alter an existing one". The post did follow
that with "(the values in the dict are mutable)", which is presumably
why garabik-2500 proposed catching __getitem__ as well as __setitem__.


Yes, I understood this after reading more. Probably easier to
solve if the problem is spelled more specifically.
I merely wanted to point out (not to you!) that there was no effective
way to capture a change to a mutable item without, as you say, modifying
the element classes.


You are completely right. This is asking for too much, unless one is
prepared to heavily modify the interpreter for debugging purposes,
which actually might be a way to solve the specific problem, once.

cheers - chris

--
Christian Tismer :^) <mailto:ti****@ stackless.com>
tismerysoft GmbH : Have a break! Take a ride on Python's
Johannes-Niemeyer-Weg 9A : *Starship* http://starship.python.net/
14109 Berlin : PGP key -> http://wwwkeys.pgp.net/
work +49 30 802 86 56 mobile +49 173 24 18 776 fax +49 30 80 90 57 05
PGP 0x57F3BF04 9064 F4E1 D754 C2FF 1619 305B C09C 5A3B 57F3 BF04
whom do you want to sponsor today? http://www.stackless.com/
Jan 13 '06 #10

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

Similar topics

57
3550
by: Egor Bolonev | last post by:
why functions created with lambda forms cannot contain statements? how to get unnamed function with statements?
4
1983
by: Vibha Tripathi | last post by:
Hi Folks, I know sets have been implemented using dictionary but I absolutely need to have a set of dictionaries...any ideas how to do that? Peace. Vibha "Things are only impossible until they are not."
1
372
by: Dave Arkley | last post by:
I have a type Dictionary<int, List<int>> oKP = new Dictionary<int, List<int>>(); Im populating the dictionary so that a key is associated with a list of integers. I then remove some, or possible all integers from the list by using foreach: foreach (int i in oKP.Keys) {
28
7348
by: robert | last post by:
In very rare cases a program crashes (hard to reproduce) : * several threads work on an object tree with dict's etc. in it. Items are added, deleted, iteration over .keys() ... ). The threads are "good" in such terms, that this core data structure is changed only by atomic operations, so that the data structure is always consistent regarding...
5
1778
by: Brian Richards | last post by:
I'm experiencing some wierd behavior with a Dictionary<T,U> class using foreach loops, such that the Key returned in the foreach is not contained in the dictionary. code: Dictionary<A, B> dict; ..... foreach(A key in dict.Keys) {
20
34123
by: Gustaf | last post by:
This is two questions in one really. First, I wonder how to convert the values in a Dictionary to an array. Here's the dictionary: private Dictionary<Uri, Schemaschemas = new Dictionary<Uri, Schema>(); Uri is the System.Uri class, and Schema is a class I made. Now, I want the class where this Dictionary is contained to have a property that...
6
10181
by: Tina I | last post by:
Hi everyone, I have a small, probably trivial even, problem. I have the following HTML: I need to make this into a dictionary like this: dictionary = {"METAR:" : "ENBR 270920Z 00000KT 9999 FEW018 02/M01 Q1004 NOSIG" , "short-TAF:" : "ENBR 270800Z 270918 VRB05KT 9999 FEW020 SCT040" , "long-Taf:" : "ENBR 271212 VRB05KT 9999 FEW020 BKN030...
2
3434
by: =?Utf-8?B?c2lwcHl1Y29ubg==?= | last post by:
Hi I have a class that inherits from Generics Dictionary The string that is used for the key is passed thru-out my pgm and sometimes it has modifiers added to the key string that are used in the system. The problem is now I have to strip the modifer to lookup in the Dictionary and I have to copy this code whenever I need to lookup the key...
3
16959
by: =?Utf-8?B?THVpZ2k=?= | last post by:
Hi all, I have a dictionary (C# 2.0) with an object (an instance of a class) for the key. The class has only a "name" field. dictionary<object, ...> When I use ContainsKey property of the dictionary to check if an object with the same "name", it returns me false.
0
7464
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7656
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7805
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7413
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7751
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
3449
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3440
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1874
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1012
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.