FAQ
I use the term "no-clobber dict" to refer to a dictionary D with
the especial property that if K is in D, then

D[K] = V

will raise an exception unless V == D[K]. In other words, D[K]
can be set if K doesn't exist already among D's keys, or if the
assigned value is equal to the current value of D[K]. All other
assignments to D[K] trigger an exception.

The idea here is to detect inconsistencies in the data.

This is a data structure I often need. Before I re-invent the
wheel, I thought I'd ask: is it already available?

TIA!

kynn

Search Discussions

  • R at Aug 3, 2009 at 9:47 pm

    On Aug 3, 4:07?pm, kj wrote:
    I use the term "no-clobber dict" to refer to a dictionary D with
    the especial property that if K is in D, then

    ? D[K] = V

    will raise an exception unless V == D[K]. ?In other words, D[K]
    can be set if K doesn't exist already among D's keys, or if the
    assigned value is equal to the current value of D[K]. ?All other
    assignments to D[K] trigger an exception.

    The idea here is to detect inconsistencies in the data.

    This is a data structure I often need. ?Before I re-invent the
    wheel, I thought I'd ask: is it already available?

    TIA!

    kynn
    Not sure if something like this already exists, but it would be
    trivial to implement by overriding dict.__setitem__()

    badda-bing baby!
  • Chris Rebert at Aug 3, 2009 at 10:00 pm

    On Mon, Aug 3, 2009 at 2:47 PM, rwrote:
    On Aug 3, 4:07?pm, kj wrote:
    I use the term "no-clobber dict" to refer to a dictionary D with
    the especial property that if K is in D, then

    ? D[K] = V

    will raise an exception unless V == D[K]. ?In other words, D[K]
    can be set if K doesn't exist already among D's keys, or if the
    assigned value is equal to the current value of D[K]. ?All other
    assignments to D[K] trigger an exception.

    The idea here is to detect inconsistencies in the data.

    This is a data structure I often need. ?Before I re-invent the
    wheel, I thought I'd ask: is it already available?

    TIA!

    kynn
    Not sure if something like this already exists, but it would be
    trivial to implement by overriding dict.__setitem__()
    That is, if you don't care about .update() not preserving the
    invariant. Otherwise, one will need to look at the UserDict module.

    Cheers,
    Chris
  • R at Aug 3, 2009 at 11:39 pm

    On Aug 3, 5:00?pm, Chris Rebert wrote:
    On Mon, Aug 3, 2009 at 2:47 PM, rwrote:
    [snip]
    Not sure if something like this already exists, but it would be
    trivial to implement by overriding dict.__setitem__()
    That is, if you don't care about .update() not preserving the
    invariant. Otherwise, one will need to look at the UserDict module.

    Cheers,
    Chris
    --http://blog.rebertia.com
    Good catch Chris. However since the OP said this was for testing
    purposes, i just *assumed* he would be smart enough *not* to call
    update() on the dict at hand ;-). But sometimes i need to be protected
    from myself too -- at least thats what my therapist keeps telling
    me :-)
  • Kj at Aug 4, 2009 at 7:30 pm
    In <mailman.4183.1249336823.8015.python-list at python.org> Chris Rebert <clp2 at rebertia.com> writes:
    On Mon, Aug 3, 2009 at 2:47 PM, rwrote:
    On Aug 3, 4:07 pm, kj wrote:
    I use the term "no-clobber dict" to refer to a dictionary D with
    the especial property that if K is in D, then

      D[K] = V

    will raise an exception unless V == D[K].  In other words, D[K]
    can be set if K doesn't exist already among D's keys, or if the
    assigned value is equal to the current value of D[K].  All other
    assignments to D[K] trigger an exception.

    The idea here is to detect inconsistencies in the data.

    This is a data structure I often need.  Before I re-invent the
    wheel, I thought I'd ask: is it already available?

    TIA!

    kynn
    Not sure if something like this already exists, but it would be
    trivial to implement by overriding dict.__setitem__()
    That is, if you don't care about .update() not preserving the
    invariant.
    The implication here is that .update() does not in turn use
    .__setitem__(), which I find a bit surprising.

    kynn
  • Chris Rebert at Aug 4, 2009 at 8:03 pm

    On Tue, Aug 4, 2009 at 12:30 PM, kjwrote:
    In <mailman.4183.1249336823.8015.python-list at python.org> Chris Rebert <clp2 at rebertia.com> writes:
    On Mon, Aug 3, 2009 at 2:47 PM, rwrote:
    On Aug 3, 4:07 pm, kj wrote:
    I use the term "no-clobber dict" to refer to a dictionary D with
    the especial property that if K is in D, then

      D[K] = V

    will raise an exception unless V == D[K].  In other words, D[K]
    can be set if K doesn't exist already among D's keys, or if the
    assigned value is equal to the current value of D[K].  All other
    assignments to D[K] trigger an exception.

    The idea here is to detect inconsistencies in the data.

    This is a data structure I often need.  Before I re-invent the
    wheel, I thought I'd ask: is it already available?

    TIA!

    kynn
    Not sure if something like this already exists, but it would be
    trivial to implement by overriding dict.__setitem__()
    That is, if you don't care about .update() not preserving the
    invariant.
    The implication here is that .update() does not in turn use
    .__setitem__(), which I find a bit surprising.
    The builtin types are allowed to take such shortcuts for performance reasons.

    Cheers,
    Chris
  • Raymond Hettinger at Aug 4, 2009 at 8:14 pm
    [kj]
    The implication here is that .update() does not in turn use
    .__setitem__(), which I find a bit surprising.
    It's never wise to make assumptions about this sort of thing.
    Every method in a class or type is allowed to directly access
    or modify its private, internal data. The implementation is
    free to choose whether to limit that access to a few accessors
    (i.e. getitem, setitem, delitem, len) or to let all of the
    methods have direct access to the underlying data structure.
    Even if accessors were used, the choice would be arbitrary
    (perhaps delitem() gets implemented in terms of pop() or somesuch).

    This is a basic for OO programming. Unless the class documentation
    promises to use particular hooks, the implementation is free to
    change in any way that doesn't violate the published API (this is
    one of the benefits of encapsulation and abstract data types).

    In general, if a subclass is overriding, rather than extending,
    then it should override *every* method that could be affected.


    Raymond
  • Steven D'Aprano at Aug 4, 2009 at 3:23 am

    On Mon, 03 Aug 2009 21:07:32 +0000, kj wrote:

    I use the term "no-clobber dict" to refer to a dictionary D with the
    especial property that if K is in D, then

    D[K] = V

    will raise an exception unless V == D[K]. In other words, D[K] can be
    set if K doesn't exist already among D's keys, or if the assigned value
    is equal to the current value of D[K]. All other assignments to D[K]
    trigger an exception.

    Coincidentally, I just built something very close to what you ask. Here
    it is:

    class ConstantNamespace(dict):
    """Dictionary with write-once keys."""
    def __delitem__(self, key):
    raise TypeError("can't unbind constants")
    def __setitem__(self, key, value):
    if key in self:
    raise TypeError("can't rebind constants")
    super(ConstantNamespace, self).__setitem__(key, value)
    def clear(self):
    raise TypeError('cannot unbind constants')
    def pop(self, key, *args):
    raise TypeError("cannot pop constants")
    def popitem(self):
    raise TypeError("cannot pop constants")
    def update(self, other):
    for key in other:
    if key in self:
    raise TypeError('cannot update constants')
    # If we get here, then we're not modifying anything,
    # so okay to proceed.
    super(ConstantNamespace, self).update(other)
    def copy(self):
    c = self.__class__(**self)
    return c



    I also have a series of unit tests for it if you're interested in them.




    --
    Steven
  • Alex23 at Aug 4, 2009 at 5:33 am

    Steven D'Aprano wrote:
    I also have a series of unit tests for it if you're interested in them.
    That's several times today that kj has asked a question and you've
    responded with ready-to-go code. If this was Stackoverflow, I'd accuse
    you of reputation-whoring...

    You _can_ just post your cool code without the double act, y'know! :)
  • Kj at Aug 4, 2009 at 7:29 pm
    In <pan.2009.08.04.03.23.19 at REMOVE.THIS.cybersource.com.au> Steven D'Aprano <steven at REMOVE.THIS.cybersource.com.au> writes:
    On Mon, 03 Aug 2009 21:07:32 +0000, kj wrote:

    I use the term "no-clobber dict" to refer to a dictionary D with the
    especial property that if K is in D, then

    D[K] = V

    will raise an exception unless V == D[K]. In other words, D[K] can be
    set if K doesn't exist already among D's keys, or if the assigned value
    is equal to the current value of D[K]. All other assignments to D[K]
    trigger an exception.
    Coincidentally, I just built something very close to what you ask. Here
    it is:
    class ConstantNamespace(dict):
    """Dictionary with write-once keys."""
    def __delitem__(self, key):
    raise TypeError("can't unbind constants")
    def __setitem__(self, key, value):
    if key in self:
    raise TypeError("can't rebind constants")
    super(ConstantNamespace, self).__setitem__(key, value)
    def clear(self):
    raise TypeError('cannot unbind constants')
    def pop(self, key, *args):
    raise TypeError("cannot pop constants")
    def popitem(self):
    raise TypeError("cannot pop constants")
    def update(self, other):
    for key in other:
    if key in self:
    raise TypeError('cannot update constants')
    # If we get here, then we're not modifying anything,
    # so okay to proceed.
    super(ConstantNamespace, self).update(other)
    def copy(self):
    c = self.__class__(**self)
    return c

    Thanks. As you note this not quite what I'm looking for, but it's
    a good template for it.

    kynn
  • Kj at Aug 4, 2009 at 8:01 pm
    In <pan.2009.08.04.03.23.19 at REMOVE.THIS.cybersource.com.au> Steven D'Aprano <steven at REMOVE.THIS.cybersource.com.au> writes:
    class ConstantNamespace(dict): <snip>
    I also have a series of unit tests for it if you're interested in them.
    Actually, come to think of it, I think I'll take you up on this.
    I'd love to see those tests. Unit testing in Python is in area I
    need to work on.

    TIA!

    kynn
  • Steven D'Aprano at Aug 5, 2009 at 3:07 am

    On Wed, 5 Aug 2009 06:01 am kj wrote:

    In <pan.2009.08.04.03.23.19 at REMOVE.THIS.cybersource.com.au> Steven
    D'Aprano <steven at REMOVE.THIS.cybersource.com.au> writes:
    class ConstantNamespace(dict): <snip>
    I also have a series of unit tests for it if you're interested in them.
    Actually, come to think of it, I think I'll take you up on this.
    I'd love to see those tests. Unit testing in Python is in area I
    need to work on.

    No problem. Here you go:

    http://www.cybersource.com.au/users/steve/python/constants.py

    Comments welcome.



    --
    Steven
  • Kj at Aug 5, 2009 at 7:58 pm
    In <00027aa9$0$2969$c3e8da3 at news.astraweb.com> Steven D'Aprano <steve at REMOVE-THIS-cybersource.com.au> writes:
    Extremely helpful. Thanks!

    kynn

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedAug 3, '09 at 9:07p
activeAug 5, '09 at 7:58p
posts13
users7
websitepython.org

People

Translate

site design / logo © 2022 Grokbase