Does Python really follow its philosophy of "Readability counts"?

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Thu Jan 22 11:56:31 EST 2009


On Thu, 22 Jan 2009 15:12:31 +0100, Bruno Desthuilliers wrote:

> Steven D'Aprano a écrit :
>> On Thu, 22 Jan 2009 10:33:26 +0100, Bruno Desthuilliers wrote:
>> 
>>> Steven D'Aprano a écrit :
>>>> On Wed, 21 Jan 2009 12:54:31 +0100, Bruno Desthuilliers wrote:
>>>>
>>>>> Russ P. a écrit :
>>>>> (snip)
>>>>>> In any case, I have suggested that Python should perhaps get a new
>>>>>> keyword, "private" or "priv".
>>>>> And quite a few people - most of them using Python daily - answered
>>>>> they didn't wan't it.
>>>> Then they don't have to use it.
>>> Yes they would. Because this would become the official way to tell
>>> what's interface and what's implementation, and *this* is the
>>> important point.
>> 
>> But if you have free access to attributes, then *everything* is
>> interface.
>> 
>> 
> Nope.

How could anyone fail to be convinced by an argument that detailed and 
carefully reasoned?



>>>> Lots of people think that double-underscore name mangling is a waste
>>>> of time: not strict enough to be useful, not open enough to be
>>>> Pythonic. Solution? Don't use double-underscore names.
>>> The name-mangling mechanism is actually useful when you want to make
>>> sure some vital implementation attribute (usually of a class intented
>>> to be extended by the library users) won't be *accidentally*
>>> overwritten.
>> 
>> Except it doesn't.
> 
> Except it works for all real-life code I've ever seen.
> 
> (snip convoluted counter-example)

"Convoluted"? It was subclassing from a class that itself was a subclass. 
This happens very frequently. The only thing that was a tiny bit unusual 
was a conjunction of two accidental name clashes: the subclass happened 
to accidentally have the same name as one of the superclasses, and both 
of them happened to have a double-underscore attribute.


> Steven, sorry for being so pragmatic, but the fact is that, from
> experience (not only mine - I'm talking about thousands of man/year
> experience), it JustWork(tm).

Double-underscore names are great for preventing name clashes, until it 
doesn't.

This isn't something new. Others have pointed out this failure mode, 
including the Timbot:

http://mail.python.org/pipermail/python-dev/2005-December/058563.html

I think the attitude towards __names illustrates a huge gulf between two 
ways of programming. One school of thought tries to write programs that 
can't fail, and considers failure modes to be bugs to be fixed. The other 
school of thought tries to write programs that won't fail until something 
unusual or unexpected happens, and behaves as if the answer to failure 
modes is "if the function breaks when you do that, then don't do that". 
Name mangling belongs in the second category.

The Python standard library has a split personality in that the parts of 
it written in C are written so they can't fail, as much as humanly 
possible. Good luck trying to get list.append() to unexpectedly fail. But 
the parts written in Python are built to a much lower standard. Look how 
easy it is to create an object with a ticking time bomb waiting to go off 
at some later date:

>>> from ConfigParser import ConfigParser
>>> config = ConfigParser({'a':1})

You've successfully created a ConfigParser object. You'd expect it should 
be safe to work with now: you haven't messed with any internals or done 
anything strange, you've just given it a default value. But then, much 
later:

>>> config.get('DEFAULT', 'a')  # or any section without option 'a'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.6/ConfigParser.py", line 545, in get
    return self._interpolate(section, option, value, d)
  File "/usr/local/lib/python2.6/ConfigParser.py", line 585, in 
_interpolate
    if "%(" in value:
TypeError: argument of type 'int' is not iterable


In stricter languages, particularly code with static type checking, the 
attitude is "you must only provide input that meets these pre-
conditions". (Often one pre-condition will be the argument type.) But in 
Python, the attitude is "you can provide any input you like, but if it 
fails, don't blame me".



-- 
Steven



More information about the Python-list mailing list