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

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sat Jan 24 06:20:07 CET 2009


On Sat, 24 Jan 2009 01:41:35 +0000, Mark Wooding wrote:

> Steven D'Aprano <steve at REMOVE-THIS-cybersource.com.au> writes:
...
>> As I see it, you have two coherent positions. On the one hand, you
>> could be like Mark Wooding, and say that Yes you want to risk buffer
>> overflows by messing with the internals
> 
> Please, point out where I said that!
> 
> I'm pretty sure that the only time I commented on this particular point
> (in message <87y6x2cih0.fsf.mdw at metalzone.distorted.org.uk>), I said:

[snip]

Yes, that was the quote I was thinking of.


> While I realise I didn't spell it out, the semantics I had in mind where
> 
>         foo.len = n
> 
> means
> 
>         if n < 0:
>           raise ValueError, 'don\'t be stupid'
>         elif len(foo) < n:
>           foo += [None] * (n - len(foo))
>         else:
>           foo[n:] = []

But that's not "messing with the internals". That's the conceptual 
equivalent of a Python getter/setter:


# Pseudo-code, untested and incomplete
class MyList(list):
    def __init__(self):
         self._length = 0
    def _getlength(self):
        return self._length
    def _setlength(self, n):
        if n < 0:
            raise ValueError("don't be stupid")
        elif len(self) < n:
            self += [None] * (n - len(self))
        else:
            self[n:] = []
        self._length = n
    len = property(_getlength, _setlength)


alist = MyList()
alist.length = 1000  # safe

This is hardly what "messing with the internals" is! If your idea of 
modifying hidden, implementation-specific details is "use a safe getter/
setter implementation that holds your hand and protects you from doing 
anything stupid", then no wonder you object to data hiding. I'd object to 
it to, if that's what I understood by it.

What I'm talking about is unsafe, direct access to the underlying C slots 
with no hand-holding. You know: messing with the internals with no nice 
safe interface between you and disaster:

alist._length = 2**128  # unsafe!



> Safety is good.  Escape hatches are good, too.

Something we can agree on.

 

>> In the second case, the next question is, why should it only be code
>> written in C that is allowed that protection?
> 
> Because Python code can't cause those sorts of problems without
> resorting to the escape hatches (e.g., ctypes).  And, very
> significantly, because C code /needs/ that protection and Python
> basically doesn't.
> 
> The basic difference is that C code is fundamentally brittle: if you
> mess up its invariants, it can crash horribly and possibly allow its
> brain to be taken over by evil people.  Python code is fundamentally
> robust.  The worst that can happen[1] is that the interpreter raises an
> exception.  This makes it ideally suited to having a more relaxed
> attitude to life.  And that, in turn, makes it approachable, hackable
> interactively, fun!

No, it's not the worst that can happen.

"I find it amusing when novice programmers believe their main job is 
preventing programs from crashing. ... More experienced programmers 
realize that correct code is great, code that crashes could use 
improvement, but incorrect code that doesn't crash is a horrible 
nightmare."
 
http://www.pphsg.org/cdsmith/types.html



-- 
Steven



More information about the Python-list mailing list