const objects (was Re: Death to tuples!)

Steven D'Aprano steve at REMOVETHIScyber.com.au
Wed Dec 14 05:58:23 EST 2005


On Wed, 14 Dec 2005 10:57:05 +0100, Gabriel Zachmann wrote:

> I was wondering why python doesn't contain a way to make things "const"?
> 
> If it were possible to "declare" variables at the time they are bound to 
> objects that they should not allow modification of the object, then we would 
> have a concept _orthogonal_ to data types themselves and, as a by-product, a 
> way to declare tuples as constant lists.

In an earlier thread, somebody took me to task for saying that Python
doesn't have variables, but names and objects instead.

This is another example of the mental confusion that occurs when you think
of Python having variables. Some languages have variables. Some do not. Do
not apply the rules of behaviour of C (which has variables) to Python
(which does not).

Python already has objects which do not allow modification of the object.
They are called tuples, strings, ints, floats, and other immutables.



> So this could look like this:
> 
>      const l = [1, 2, 3]

(As an aside, it is poor practice to use "l" for a name, because it is too
easy to mistake for 1 in many fonts. I always use capital L for quick
throw-away lists, like using x or n for numbers or s for a string.)

Let's do some tests with the constant list, which I will call L:


py> L.count(2)
1
py> L.append(4)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ConstantError: can't modify constant object

(Obviously I've faked that last error message.) So far so good: we can
call list methods on L, but we can't modify it.

But now look what happens when we rebind the name L:

py> L = 2
py> print L
2

Rebinding the name L doesn't do anything to the object that L pointed to.
That "constant list" will still be floating in memory somewhere. If L was
the only reference to it, then it will be garbage collected and the memory
it uses reclaimed.


Now, let's look at another problem with the idea of constants for Python:

py> L = [1, 2, 3]  # just an ordinary modifiable list
py> const D = {1: "hello world", 2: L}  # constant dict

Try to modify the dictionary:

py> D[0] = "parrot"
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ConstantError: can't modify constant object

So far so good.

py> L.append(4)

What should happen now? Should Python allow the modification of ordinary
list L? If it does, then this lets you modify constants through the back
door: we've changed one of the items of a supposedly unchangeable dict.

But if we *don't* allow the change to take place, we've locked up an
ordinary, modifiable list simply by putting it inside a constant. This
will be a great way to cause horrible side-effects: you have some code
which accesses an ordinary list, and expects to be able to modify it. Some
other piece of code, could be in another module, puts that list inside a
constant, and *bam* your code will break when you try to modify your list.

Let me ask you this: what problem are you trying to solve by adding
constants to Python? 



> It seems to me that implementing that feature would be fairly easy.
> All that would be needed is a flag with each variable.

Surely not. Just adding a flag to objects would not actually implement the
change in behaviour you want. You need to code changes to the parser to
recognise the new keyword, and you also need code to actually make objects
unmodifiable.



-- 
Steven.




More information about the Python-list mailing list