Read-only attribute in module

Steven D'Aprano steve+comp.lang.python at pearwood.info
Thu Feb 9 20:04:41 EST 2012


On Thu, 09 Feb 2012 23:32:59 +1100, Ben Finney wrote:

> Mateusz Loskot <mateusz at loskot.net> writes:
> 
>> I'm wondering, is there any mean to implement attribute in module scope
>> which is read-only?
> 
> Python is designed by and for consenting adults. Rather than
> restricting, instead use conventions to make your intent clear to the
> user of your library.

Oh I agree. The convention I want to use to make my intent clear is the 
same convention used for the rest of Python: a runtime exception.

I find this "consenting adults" argument less than convincing. We already 
have constants in Python -- every int and float and string is a constant. 
You can't modify the object 1 to have the value 42, and for very good 
reason, "consenting adults" be damned.

What we don't have is *named* constants.

Python has no shortage of read-only values and members, e.g.:

>>> class A(object):
...     pass
...
>>> A.__dict__ = {}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: attribute '__dict__' of 'type' objects is not writable


Consider this:

If you pass an int to len(), you get a runtime error telling you that you 
did something wrong. Does this violate "consenting adults"? No, if you 
want to, you can monkey-patch len to accept ints, but you have to work at 
it. The normal behaviour is to get an error, not some arbitrary but 
meaningless behaviour. You certainly don't get told to use a naming 
convention (Hungarian notation, perhaps) to avoid passing the wrong value 
to len().

If you assign to something which is intended to be constant, you don't 
get an exception telling you that you made a mistake. Instead, you get 
unspecified (but almost certainly incorrect) behaviour in the module, and 
told to use a naming convention to remind you not to screw up.

The excuse given is that Python is for "consenting adults", but I don't 
believe it. I believe that the real reason is that it is hard to 
introduce named constants to Python, and rather than solve that hard 
problem, people just whitewash the issue and pretend that it's a feature. 
It's not a feature, it's a wart. There is no conceivable use-case for 
allowing math.pi = 2.5 to succeed.

Python happily violates "consenting adults" all over the place. We have 
properties, which can easily create read-only and write-once attributes. 
We have descriptors which can be used for the same. We have immutable 
types, and constant values, but not constant names.

Python can enforce all common software contracts I can think of, except 
the contract that a name will be set to a specific value. And that is, in 
my opinion, a weakness in Python.


-- 
Steven



More information about the Python-list mailing list