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