Why does python not have a mechanism for data hiding?
ncoghlan at gmail.com
Wed Jun 4 13:12:00 CEST 2008
On May 26, 7:32 am, "Joe P. Cool" <joe.p.c... at googlemail.com> wrote:
> I saw this "don't need it" pattern in discussions about the ternary
> "if..else" expression and about "except/finally on the same block
> Now Python has both.
if/else was added solely because people kept coming up with ways of
embedding a pseudo conditional inside expressions and writing buggy
code in the process. All it really saves you in practice is a bit of
vertical whitespace, so, no, you still don't need it - but if you
insist on doing it, at least there's now an easy way to do it
except/finally on the same block level was trivial to implement once
the reference interpreter switched to an AST based compiler for 2.5.
If you look at the AST, you'll find that it still only has TryExcept
and TryFinally, so again, you still don't need except/finally on the
same block level - all the syntax allows you to do is omit the second
try: line and its associated indentation.
> Actually it is very useful to be able to
> between inside and outside. This is obvious for real world things e.g.
> TV. Nobody likes to open the rear cover to switch the channel. Similar
> arguments apply to software objects. "data hiding" is a harsh name, I
> call it "telling what matters". The need for this becomes
> indispensable in
> really big software packages like the Eclipse framework with approx.
> classes. If you cannot tell the difference between inside and outside
> are lost.
> > In Python, the philosophy "we're all consenting adults here" applies.
> Please don't sell a missing feature as a philosophy. Say you don't
> it. But don't call it philosophy.
Gosh, and here I thought treating programmers as non-idiots was
actually one of the guiding philosophies in the discussion on python-
dev. Good thing we have you here to tell us we're only imagining that.
> > You shouldn't pretend to know, at the time you write it, all the uses
> > to which your code will be put.
> It's *your* *decision* which uses will be available. Your explanation
> to me as a fear to decide.
Are you writing application code or library code? For application
code, you have a much greater idea of the uses for your code, so you
can be confident in your decision as to what should and should not be
visible. For library code, however, it's fairly common for a library
to provide something which is almost, but not quite, what the user
needs. Letting users poke around at their own risk is a nice courtesy
that can save them a lot of work in the long run.
So the decision to hide something is still made (by using an
underscore prefix), but an easy mechanism is provided for the library
user to override that decision.
> > If you want the users of your code to know that an attribute should
> > not be used as a public API for the code, use the convention of naming
> > the attribute with a single leading underscore.
> Littering your class definition with dozens of underscores is exactly
> line noise we love to criticize in Perl.
Using underscores in names (leading or otherwise) separated by
plaintext keywords is a far cry from multiple different symbols that
mean different things in different contexts and can be chained
together fairly arbitrarily.
> > > Python advertises himself as a full OOP language, but why does it
> > > miss one of the basic principles of OOP?
> > Who taught you that enforced restrictions on attribute access was a
> > "basic principle" of OO?
> Nearly every introduction to OOP? Please don't tell me that
> does not mean "enforced restriction". If the language has no syntactic
> support for encapsulation then it does not have encapsulation.
Module globals aren't visible outside the module without importing it.
Class attributes aren't visible outside the class without derefencing
Instance attributes aren't visible outside an instance without
*That* is the encapsulation/data hiding which OOP requires, and is the
kind which Python enforces. What you're asking for is encapsulation of
class and instance attributes based on the context in which the
dereferencing occurs (inside the class, inside a subclass of that
class, inside an instance of that class, inside an instance of a
subclass of that class, somewhere else entirely), and that has nothing
to do with the basics of OOP.
On the other hand, if you're so keen on this feature, perhaps you'd
like to make a concrete proposal regarding how you would like the
semantics to work in light of Python dynamic typing model. What will
it do when a method is invoked via the class dict rather than via
attribute retrieval? Can unbound methods access protected or private
attribute? How about descriptor get, set and delete methods? What
happens when a function is added to a class definition after creation
as a new method?
More information about the Python-list