Why less emphasis on private data?

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Sun Jan 7 16:42:11 EST 2007


John Nagle a écrit :
> sturlamolden wrote:
> 
>> time.swift at gmail.com wrote:
>>
>>> Coming from a C++ / C# background, the lack of emphasis on private data
>>> seems weird to me. I've often found wrapping private data useful to
>>> prevent bugs and enforce error checking..
>>>
>>> It appears to me (perhaps wrongly) that Python prefers to leave class
>>> data public.  What is the logic behind that choice?
>>
>>
>>
>> The designers of Java, C++, C#, Ada95, Delphi, etc. seem to think that
>> if an object's 'internal' variables or states cannot be kept private,
>> programmers get an irresistible temptation to mess with them in
>> malicious ways.
> 
> 
>     If you're not clear on encapsulation issues,

encapsulation != data hiding

> you probably haven't
> done extensive maintenance programming on code written by others.

I did.

> Finding out who can mess with a variable when debugging the code of
> others is not fun.

# before
class Toto(object):
   def __init__(self, x):
     self._x = x

# after
class Toto(object):
   def __init__(self, x):
     self._x = x

   @apply
   def _x():
     def fget(self):
       return self._real_x
     def fset(self, value):
       import pdb; pdb.set_trace()
       self._real_x = value
     return property(**locals)

This is of course a braindead implementation - a better one would use 
either the inspect module of the sys._getframe() hack to retrieve useful 
debug infos (left as an excercice to the reader...)


>     Because Python doesn't have explicit declarations, scope of 
> variables is
> a touchy issue.

???

>  If you write "x = 1" within a function, that will
> create a local "x" if "x" doesn't exist, or alter a global "x" if "x" was
> previously created in the global context.

Err... May I suggest you to read these two pages:
http://docs.python.org/ref/assignment.html
http://docs.python.org/ref/global.html#l2h-563

>  But at least global variables
> are local to the namespace; we don't have clashes across files.  So
> it's not too bad.  JavaScript has the convention that newly created
> variables are global by default.  

Unless preceded by the 'var' keyword...

> Big mistake.

Mmm... which one ?

>     The underscore thing makes sense.  Single underscore
> variables are "protected" in the C++ sense, and double underscore
> variables are "private", not visible from inherited classes.
> It's hard to misuse such variables by accident.  I'd be tempted
> to prohibit access to underscore variables other than via "self._x"
> forms, so they'd be inaccessable outside the object. 

# foo.py
class Foo(object):
   def __init__(self, x):
     self._x = x
   def __repr__(self):
     return "<Foo %s>" % self._x

# bar.py
def bar(self):
   self.y = self._x

# baaz.py
from foo import Foo
from bar import bar
Foo.bar = bar

f = Foo([42])
f.bar()
f.y.append('gotcha')
print f


> It's undesirable
> from a maintenance standpoint to have an unenforced convention

If it's a convention, it doesn't have to be inforced. If it's inforced, 
it's not a convention anymore.

While we're at it, I've found it very valuable to be able to mess with 
implementation when doing maintenance on somewhat large (and somewhat 
messy) Python systems...

> like
> a lead underscore.  The maintenance programmer can't trust its meaning.
 >
>     As Python grows up, and larger systems are written in it, these
> issues become more important.

If you go that way, then you'll also want to introduce declarative 
static typing and remove all possibility to dynamically modify classes 
or add/replace attributes and/or methods on a per-instance basis. If you 
want Java, you know where to find it.



More information about the Python-list mailing list