Immutable instances, constant values

Steven D'Aprano steve at REMOVETHIScyber.com.au
Sat Nov 19 11:45:40 CET 2005


On Fri, 18 Nov 2005 14:32:46 +1100, Ben Finney wrote:

> Is there any difference between a Python immutable value, and a
> constant? I suppose "constant" also implies that the *name* binds
> unchangeably to a particular value. Is that meaningful?

That's precisely how I understand "constant" to be useful. Consider:

c = 2.9979246e+08 # speed of light in metres per second

def energy(mass):
    """Converts mass in kilograms to energy in joules"""
    return mass*c**2

That works fine until the name c is rebound to some other value. The fact
that the float object 2.9979246e+08 is immutable is necessary but not
sufficient.


> How does one actually ensure an object is immutable? Is it a matter of
> overriding a bunch of methods, or is ther a neater way?
> 
> Is it bad style to make a user-defined class that creates immutable
> objects? Why?

I can't see why it would be bad style. That's what FrozenSet does.

> In the case of 'enum', can anyone argue for or against an enumerated
> type being immutable? Its values being constant?

According to Gary Larson, there are four fundamental types of people. You
can tell them apart from their reaction to being given a half-filled glass:

"The glass is half full."

"The glass is half empty."

"Half full. No, half empty! No, half full. Wait... what was the question?"

"Hey! I ordered a cheeseburger!"

We might handle this with:

states = Enum("full", "empty", "indeterminate", "cheeseburger")

which then get referred to with:

states.full
states.empty
states.indeterminate
states.cheeseburger

I might decide that "argumentative" is a better label than "cheeseburger",
and mutate the appropriate enum value. What should happen? I see three
possibilities:

(1) states.cheeseburger still hangs around, but is not equivalent to
states.argumentative, in much the same way that reloading a module can
leave obsolete objects in your namespace (reloading doesn't automatically
cause names that point to objects from a module to rebind to new objects).

(2) references to states.cheeseburger raise an exception

(3) references to states.cheeseburger are equivalent to
states.argumentative. A rose by any other name. It shouldn't matter what
label we put on the enums, in principle.

Possibility (1) is obviously Bad with a Capital B, and should be avoided.

Possibility (2) has the saving grace that it is no different to what
happens if you rebind class attributes. There is an argument that if you
can rebind class attributes, you should be able to rebind enums and face
the consequences (good bad or indifferent) as best you can.

Possibility (3) is the logical solution. It shouldn't matter what labels
we put on the enums. But I fear not practical unless the enums are
implemented as Singletons (multitons?), and perhaps not even then. 

Alternatively, you could bypass the whole problem by making enums
immutable.


-- 
Steven.




More information about the Python-list mailing list