Discussion:
[Tutor] Data hiding in Python.
Don Taylor
2006-12-18 16:47:32 UTC
Permalink
I am working my way through 'wxPython in Action' by Noel Rappin and
Robin Dunn and came across this comment about data hiding in their
explanation of the MVC pattern:

".. the View... should never get to see the private internals of the
Model. Admittedly, this is difficult to enforce in Python, but one way
to help enforcement it is to create an abstract Model class that defines
the API that the View can see. Subclasses of the Model can either act
as proxies for an internal class that can be changed, or can simply
contain the internal workings themselves. The first option is more
structured, the second easier to implement."

I like the idea of data hiding but Googling 'Python data hiding' yields
lots of discussion to the effect that it cannot/should not be done.

So what do the authors mean? They do not give any examples of this
technique (at least not so far as I have read in the book) so I have
been trying to figure something out. And then, is it worth the trouble?

Any suggestions? Preferably with code fragments.

Here is what I have got so far:

A calling module:
-caller.py---------------------------------------------------------------------

import model

if __name__ == '__main__':
model.methodA() # test a method call interface
testInstance = model.TestClass() #test a class generation interface
testInstance.methodB() # test a method call within the new class
-------------------------------------------------------------------------------

The actual model module, which does not contain any (or much)
implementation code:
-model.py----------------------------------------------------------------------

import innermodel

__implementation = innermodel.Implementation()

def methodA():
"Example of a method interface."
__implementation.methodA()

def TestClass():
"Example of a class interface."
return __implementation.TestClass()

-------------------------------------------------------------------------------

and then the actual implementation code:
-innermodel.py-----------------------------------------------------------------

class Implementation:
def __init__(self):
print "Implementation initializing..."

def methodA(self):
print "Implementation methodA called."

class TestClass:
def __init__(self):
print "TestClass initializing..."

def methodB(self):
print "TestClass methodB called."
-------------------------------------------------------------------------------

I am not sure if this is what they mean, and if so which is this - a
proxy for an internal class that can be changed, or does it simply
contain the internal workings.

It seems to provide some degree of data hiding, but perhaps too much?
You cannot figure out from the model.py file what are the available
methods for the TestClass class. I guess that these could be documented
in the TestClass docstring.

Don.
Kent Johnson
2006-12-19 18:26:14 UTC
Permalink
Post by Don Taylor
I am working my way through 'wxPython in Action' by Noel Rappin and
Robin Dunn and came across this comment about data hiding in their
".. the View... should never get to see the private internals of the
Model. Admittedly, this is difficult to enforce in Python, but one way
to help enforcement it is to create an abstract Model class that defines
the API that the View can see. Subclasses of the Model can either act
as proxies for an internal class that can be changed, or can simply
contain the internal workings themselves. The first option is more
structured, the second easier to implement."
I like the idea of data hiding but Googling 'Python data hiding' yields
lots of discussion to the effect that it cannot/should not be done.
Python culture tends towards "we're all consenting adults here". If you
attempt to shoot yourself in the foot, you should get some kind of
warning that perhaps it is not what you really want to do, but if you
insist, hey, go ahead, it's your foot!

With regard to data hiding this means using leading underscore for names
that are considered implementation details, this is fair warning to
clients to use them at your own risk.
Post by Don Taylor
So what do the authors mean? They do not give any examples of this
technique (at least not so far as I have read in the book) so I have
been trying to figure something out. And then, is it worth the trouble?
My vote is, no, not worth the trouble. It's Java / C++ / static-typing /
put-the-client-in-a-straightjacket-so-they-don't-touch-anything thinking.
Post by Don Taylor
Any suggestions? Preferably with code fragments.
-caller.py---------------------------------------------------------------------
import model
model.methodA() # test a method call interface
testInstance = model.TestClass() #test a class generation interface
testInstance.methodB() # test a method call within the new class
-------------------------------------------------------------------------------
The actual model module, which does not contain any (or much)
-model.py----------------------------------------------------------------------
import innermodel
__implementation = innermodel.Implementation()
"Example of a method interface."
__implementation.methodA()
"Example of a class interface."
return __implementation.TestClass()
-------------------------------------------------------------------------------
-innermodel.py-----------------------------------------------------------------
print "Implementation initializing..."
print "Implementation methodA called."
print "TestClass initializing..."
print "TestClass methodB called."
-------------------------------------------------------------------------------
I am not sure if this is what they mean, and if so which is this - a
proxy for an internal class that can be changed, or does it simply
contain the internal workings.
Neither, really. You haven't provided the abstract base class to show
the API, and you are not really delegating to Implementation.TestClass.
methodA() (which is not a method) is a proxy function because it
delegates to __implementation.
Post by Don Taylor
It seems to provide some degree of data hiding, but perhaps too much?
Not really, clients can still access __implementation, it's just a
little harder.
Post by Don Taylor
You cannot figure out from the model.py file what are the available
methods for the TestClass class. I guess that these could be documented
in the TestClass docstring.
Ask yourself what is the benefit of all this?

Kent
Jonathon Sisson
2006-12-19 21:13:11 UTC
Permalink
Post by Kent Johnson
My vote is, no, not worth the trouble. It's Java / C++ / static-typing /
put-the-client-in-a-straightjacket-so-they-don't-touch-anything thinking.
Heh...and don't forget the king-pin of them all, C#. Between private,
public, protected, internal, and protected internal I lose track of what
I was originally doing and end up contemplating the meaning of "what if
another programmer wants to use this creation of mine" instead of doing
what I set out to do...

I'm with Kent on this one...definitely not worth the trouble to
bastardize Python like that...

As a side note, does anyone have a good argument for access level
controls like C#? I personally think it's a waste of time (much like
C#/ASP.NET...my apologies to any .NET fans out there...), and honestly
the arguable margin of security that access modifiers provide is
outweighed by the cons, in my opinion. (And usually what programmers
end up doing is creating "service methods" that allow access anyways, so
the margin of "security" is lost). Thoughts?

Jonathon
Alan Gauld
2006-12-19 21:23:29 UTC
Permalink
Post by Jonathon Sisson
As a side note, does anyone have a good argument for access level
controls like C#?
These kinds of controls do help in large projects with many
teams, often geographically dispersed. It is a form of
documentation about the intent of the class designer,
but also enforces that intent. This is espectially important
during the early development of libraries where the internal
representation is constantly evolving.

The use of these access modifiers also provides an extra
level of namespace control in some cases.

However, that having been said I think anything beyond
public/private is overkill. I actually like the Delphi 2 model
(they have since added protected etc) was a good compromise
where implementation section(*) attributes could be seen
within a module even by other classes, but not outside
the module. By combining that with public/private declarations
in the class you had good control but much less confusion
than in C++ etc.

For smaller programs the whole mess is overkill and the
Python approach of consenting adults makes much more
sense IMHO.
Post by Jonathon Sisson
I personally think it's a waste of time (much like
C#/ASP.NET...my apologies to any .NET fans out there...)
The whole .NET thing is pretty neat, except that it could have
all been done using Java and thius avoided a language war.
But multiple languages compiling to a common runtime
all with a single class library is powerful medicine...
Post by Jonathon Sisson
end up doing is creating "service methods" that allow access
anyways, so
the margin of "security" is lost). Thoughts?
And here I agree. So called getters/setters for every attribute
are a JavaBeans kluge that eats away at the very essence
of OOP - like so much in Java... Appropriate accessor methods
are fine but they should be used with great caution, classes
should expose behaviours not attributes!
--
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld
Jonathon Sisson
2006-12-19 23:07:08 UTC
Permalink
Post by Alan Gauld
but also enforces that intent. This is espectially important
during the early development of libraries where the internal
representation is constantly evolving.
Yeah, I would have to agree with you there. I hadn't considered that
angle...
Post by Alan Gauld
But multiple languages compiling to a common runtime
all with a single class library is powerful medicine...
I would argue the only real "innovation" provided by .NET is just that:
the ability to produce and consume project components from different
languages.

I have to say I'd still prefer Java development over .NET, but that's
probably more personal issues with Microsoft than language implementation.

I recently used Python for a relatively large project for a Linux
scripting class (the professor was kind enough to allow any relatively
common scripting language (i.e. available on our Linux server...heh))
and I have to admit, I'm much more productive with Python than with
virtually any language I've used before. (No, I haven't tried Ruby yet,
but I hear it's just as addicting). Access modifiers or not, you can't
really argue with development productivity like that...or the grade that
I got on that project. =) And, it was actually kind of fun listening to
some other students gripe about Perl...haha.

Anyhow, thanks for the additional info, Alan!

Jonathon
Alan Gauld
2006-12-20 01:04:40 UTC
Permalink
Post by Alan Gauld
public/private is overkill. I actually like the Delphi 2 model
(they have since added protected etc) was a good compromise
where implementation section(*) attributes
Oops!
I meant to add a footnote here that explained that Delphi modules
comprise two sections, an interface and an implementation. Only
functions declared in the interface can be used by clients of the
module. I often think that this scheme would be a useful addition
to Python's module structure. It would look something like this:

#### module foo ####
interface:

def myfunc(p1,p2)

def anotherFunc(p3)

class bar:
def __init__(...)
def f(self)
def g(self,x)

mylist = [] # can be used by clients

implementation:

secretVar = {} # hidden from clients

def myfunc(p1,p2):
#code here can use secretVar

def anotherFunc(p3):
# code here

class bar:
def __init__(self):
self.x = 42
# etc...
#########################

Its fairly easy to understand and provides a good mix of
access control and readability without tying the programmers
hands.

It also means you can very easily see all that a module has
to offer by just reading the top (relatively) few lines of code.
It thus gives the advantages of C header files without the
problems of managing/synchronising two files per module.

All IMHO of course... :-)

Alan G.
Andreas Kostyrka
2006-12-20 02:01:22 UTC
Permalink
Post by Jonathon Sisson
Post by Kent Johnson
My vote is, no, not worth the trouble. It's Java / C++ / static-typing /
put-the-client-in-a-straightjacket-so-they-don't-touch-anything thinking.
Heh...and don't forget the king-pin of them all, C#. Between private,
public, protected, internal, and protected internal I lose track of what
I was originally doing and end up contemplating the meaning of "what if
another programmer wants to use this creation of mine" instead of doing
what I set out to do...
I'm with Kent on this one...definitely not worth the trouble to
bastardize Python like that...
As a side note, does anyone have a good argument for access level
controls like C#? I personally think it's a waste of time (much like
C#/ASP.NET...my apologies to any .NET fans out there...), and honestly
the arguable margin of security that access modifiers provide is
outweighed by the cons, in my opinion. (And usually what programmers
end up doing is creating "service methods" that allow access anyways, so
the margin of "security" is lost). Thoughts?
Well, what does make sense at least in a static language situation is
to support an arbitrate number of "interfaces", e.g. like Modula3 is
providing with partial revealing the exact type of an opaque type.

Basically, taking the classical IO stream example, you get the
following roles:

*) simple user
*) advanced user (does it's own thread locking, unsafe)
*) implementer (simple)
*) advanced implementer (does it's own buffer management)

and so on.

All this is not really covered by public/protected/private, because
depending upon your relationship with the class, you might different
levels of access.

Python as a dynamic language in practice does not need access roles
like the above, albeit a comparable service is provided by
zope.interfaces.

Andreas

Loading...