Why does python not have a mechanism for data hiding?

Arnaud Delobelle arnodel at googlemail.com
Mon May 26 17:07:11 EDT 2008


"Russ P." <Russ.Paielli at gmail.com> writes:

> On May 26, 9:08 am, "Gabriel Genellina" <gagsl-... at yahoo.com.ar>
> wrote:
>> En Mon, 26 May 2008 06:14:19 -0300, Paul Boddie <p... at boddie.org.uk> escribió:
>>
>> >> I am also bothered a bit by the seeming inconsistency of the rules for
>> >> the single underscore. When used at file scope, they make the variable
>> >> or function invisible outside the module, but when used at class
>> >> scope, the "underscored" variables or functions are still fully
>> >> visible. For those who claim that the client should be left to decide
>> >> what to use, why is the client prohibited from using underscored
>> >> variables at file scope?
>>
>> > I don't remember why this is. I'll leave you to track down the
>> > rationale for this particular behaviour. ;-)
>>
>> There is no rationale because this is not how it works...
>> You can:
>> - import a module and access *all* of their names, even names prefixed with an underscore
>> - import any name from a module, even if it starts with an underscore
>> - import * from a module, and it will import all names listed in __all__, even if they start with an underscore
>>
>> Only in that last case, and when the module doesn't define __all__, the list of names to be imported is built from all the global names excluding the ones starting with an underscore. And it seems the most convenient default. If one wants to access any "private" module name, any of the first two alternatives will do.
>>
>> --
>> Gabriel Genellina
>
>
> Well, that's interesting, but it's not particularly relevant to the
> original point. By default, underscored variables at file scope are
> not made visible by importing the module in which they appear. But
> underscored member variables of a class *are* made visible to the
> client by default. That's seems at least slightly inconsistent to me.

Apart from the fact that modules and classes are very different ideas,
look at this code:

========================================
import random

class A(object):
    def __init__(self, val):
        self._val = val

class B(A):
    def f(self, other):
        return random.choice([self, other])._val

a = A(1)
b = B(2)

b.f(a)
========================================

So you want the last line to return 2 if b is chosen and raise a
ValueError if a is chosen.  Good luck implementing that!

        
> The issue here, for me at least, is not whether the data or methods
> should be absolutely hidden from the client. I'm perfectly willing to
> say that the client should have a back door -- or even a side door --
> to get access to "private" data or methods.
>
> But I also believe that some standard way should be available in the
> language to tell the client (and readers of the code) which methods
> are *intended* for internal use only. And that method should be based
> on more than a naming convention. Why? Because (1) I don't like
> leading underscores in my identifiers, and (2) I think I should be
> free to choose my identifiers independently from their properties.

Python is a dynamic language, attributes can be added to objects at
any time in their life.  Consider:

class A(object):
    private x # Suspend belief for a minute...
    def __init__(self, x):
        self.x = x

a = A()
a.x = 2 # What behaviour do you propose here?

> Is this a major issue? No. Is it a significant issue. Yes, I think so.
>
> Here's another suggestion. Why not use "priv" as shorthand for
> "private"? Then,
>
> priv height = 24
>
> at file scope would make "height" invisible outside the module by
> default. And the same line in a class definition would give "height"
> the equivalent of "protected" status in C++.
>
> I think "height" looks cleaner than "_height". And isn't clean code a
> fundamental aspect of Python?

I didn't use to be very fond of it either but I have to admit that it
conveys very useful information.

-- 
Arnaud



More information about the Python-list mailing list