locking dictionaries (was Re: New statement proposal for Python)

Alex Martelli aleaxit at yahoo.com
Sat Jun 16 11:16:35 CEST 2001


"Nick Perkins" <nperkins7 at home.com> wrote in message
news:oBwW6.245227$eK2.51902394 at news4.rdc1.on.home.com...
>
> "Alex Martelli" <aleaxit at yahoo.com> wrote in message >
>
> <snip excellent comments re: 'constants'>

Tx for the 'excellent':-).

> > One (IMHO) Python enhancement would be to give dictionaries
> > some finer-grained control on their degree of mutability.
> > The ability to selectively make SOME existing keys non
> > rebindable and/or non removable _would_ come in handy in
    ...
> now, that's an interesting idea.
> how would that look, syntactically?

Haven't thought about in PEP-sufficient details...:-)

> dict['A']=1
> dict.lock('A')
>
> ..making the value unchangeable?

Un-rebindable, to be precise -- i.e.:

    dict['A'] = list("ciao")
    dict.setlock(1, 'A')
    dict['A'].append("plip")
    print dict['A']
ciaoplip

would work -- so the value is still changeable in the sense of
'mutable'.  Sorry, this IS a pedantic distinction, but it can be
important.  What I (somewhat vaguely) had in mind was a
.setlock() method (it may be important to have a .getlock one
for introspection, too) able to associate 'lock-bits' with...:
    -- specific keys,
    -- all keys in the dictionary,
    -- all keys NOT in the dictionary
and the lock-bits might inhibit one or more of:
    -- binding
    -- rebinding
    -- deleting
    -- changing the lockbits themselves
and that's where it bogged down last time (before we got to
the syntax) -- my correspondant was appalled at the idea of
using 'bits' to overtly encode 'a set of options' and I could
not find an alternative, as Python lacks 'sets'.

Assuming one can stomach 'bits' (or some, e.g., encoding
as string thereof, such as the mode parameter to 'open'),
putting the bits first in setlock has the advantage that the
other parameters to setlock can be optional.  So...:
    dict.setlock(n)
sets bits n as the lockbits for all keys not in the dictionary,
    dict.setlock(n, 'A')
sets bits n as the lockbits for key 'A' (which must be in
the dictionary right now, else KeyError is raised),
    dict.setlock(n, 'A', 'B', 'C')
sets bits n for three keys,
    dict.setlock(n, *dict)
sets them for all keys currently in the dictionary if a dictionary
can be used as a sequence (as seems to be true in Python 2.2).

A dictionary whose lockbits are set to forbid ANY rebinding,
deleting, new-key binding, AND change to the lockbits, could
suddenly and logically sprout hashability, since it becomes an
acceptable key IF it has hashable values (much like a tuple --
if the items are changeable, the fact that the _container_ is
not does not suffice).  But that's an aside, I guess.


> ..and would attempts to set the value raise an exception?

Exactly -- that seems to be the only Pythonic approach.  The
key added-value of this hypothetical proposal would be to
help you avoid accidental rebinding or deletion, or accidental
addition of new keys, to a dictionary that you have decided
must not be further changed in such ways.

For example,
    sys.modules[__name__].__dict__.setlock(n)
or if supported (if globals() WAS defined as equivalent...):
    globals().setlock(n)
for an appropriate n would say "no more new keys can be
bound in the current module's dictionary" -- giving much
of the effect of optional "variable declarations" for the
global variables of this module.  Not the most crucial
need in the world, but I think it WOULD be a helpful
psychological crutch to know you COULD do that if needed,
to get Python more widely accepted.  And no special purpose
machinery would be needed -- just an application of various
useful mechanisms in orthogonal ways... very Pythonic IMHO.

Easy to dress up in a function of course, as would be some
other construct such as
    magic=23
    globals().setlock(n,'magic')
to make magic a non-rebindable "constant".  Etc, etc.


Alex






More information about the Python-list mailing list