473,287 Members | 1,741 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,287 software developers and data experts.

Why does python not have a mechanism for data hiding?

Hi,

first, python is one of my fav languages, and i'll definitely keep
developing with it. But, there's 1 one thing what I -really- miss:
data hiding. I know member vars are private when you prefix them with
2 underscores, but I hate prefixing my vars, I'd rather add a keyword
before it.

Python advertises himself as a full OOP language, but why does it miss
one of the basic principles of OOP? Will it ever be added to python?

Thanks in advance,
Lucas
Jun 27 '08 #1
162 10009
Sh4wn <lu*********@gmail.comwrites:
first, python is one of my fav languages, and i'll definitely keep
developing with it. But, there's 1 one thing what I -really- miss:
data hiding. I know member vars are private when you prefix them with
2 underscores, but I hate prefixing my vars, I'd rather add a keyword
before it.
From whom are you trying to hide your attributes?

In Python, the philosophy "we're all consenting adults here" applies.
You shouldn't pretend to know, at the time you write it, all the uses
to which your code will be put. Barriers such as enforced "private"
attributes will only cause resentment when people, despite your
anticipations, *need* to access them and are then forced to hack their
way around them.

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. This is a string
signal that the attribute is part of the implementation, not the
interface. The reader is then on notice that they should not rely on
that attribute; but they are not *prohibited* from using it if
necessary to their ends.
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?

Perhaps you're confusing the "encapsulation" and "abstraction"
principles for enforced access restrictions; they're not.
Will it ever be added to python?
I hope not.

--
\ "Why was I with her? She reminds me of you. In fact, she |
`\ reminds me more of you than you do!" -- Groucho Marx |
_o__) |
Ben Finney
Jun 27 '08 #2
Ben Finney <bi****************@benfinney.id.auwrites:
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. This is a
string signal that the attribute is part of the implementation, not
the interface.
Quite apart from whether it's a string signal, I meant to write that
it's a *strong* signal.

--
\ "Some people, when confronted with a problem, think 'I know, |
`\ I'll use regular expressions'. Now they have two problems." |
_o__) —Jamie Zawinski, in alt.religion.emacs |
Ben Finney
Jun 27 '08 #3
On May 24, 2:58 pm, Ben Finney <bignose+hates-s...@benfinney.id.au>
wrote:
Sh4wn <luckyluk...@gmail.comwrites:
first, python is one of my fav languages, and i'll definitely keep
developing with it. But, there's 1 one thing what I -really- miss:
data hiding. I know member vars are private when you prefix them with
2 underscores, but I hate prefixing my vars, I'd rather add a keyword
before it.

From whom are you trying to hide your attributes?
Actually, 'data hiding', although vastly overused by the static crowd
can be a reasonable thing to want.

For example, at Resolver Systems we expose the spreadsheet object
model to our users. It hasa public, documented, API - plus a host of
undocumented internally used methods.

We would really *much* rather hide these, because anything our
customers start using (whether documented or not) we will probably
have to continue supporting and maintaining.

The 'we told you not to use that' approach, when applied to paying
customers doesn't really work... all they see is that you broke their
spreadsheet code by changing your API.

You can make members truly private by proxying, but it is a bit
ungainly.

Michael Foord
http://www.ironpythoninaction.com/

>
In Python, the philosophy "we're all consenting adults here" applies.
You shouldn't pretend to know, at the time you write it, all the uses
to which your code will be put. Barriers such as enforced "private"
attributes will only cause resentment when people, despite your
anticipations, *need* to access them and are then forced to hack their
way around them.

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. This is a string
signal that the attribute is part of the implementation, not the
interface. The reader is then on notice that they should not rely on
that attribute; but they are not *prohibited* from using it if
necessary to their ends.
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?

Perhaps you're confusing the "encapsulation" and "abstraction"
principles for enforced access restrictions; they're not.
Will it ever be added to python?

I hope not.

--
\ "Why was I with her? She reminds me of you. In fact, she |
`\ reminds me more of you than you do!" -- Groucho Marx |
_o__) |
Ben Finney
Jun 27 '08 #4
Fuzzyman <fu******@gmail.comwrites:

The 'we told you not to use that' approach, when applied to paying
customers doesn't really work... all they see is that you broke
their spreadsheet code by changing your API.
And the customer point of view is quite reasonable - they have a job
to do, and a limited timeframe; sometimes accessing privates directly
is much better than waiting for updates from vendor. Bad designs (as
far as choosing publics goes) happen.

Even if their softare breaks on upgrade, you can quite clearly point
out that they used an internal api - and they will keep on using the
old version until they solve the problem. Everybody wins.

Perhaps a lint-like validation tool would be optimal for this
problem...

Jun 27 '08 #5
On May 24, 4:56*pm, vivai...@gmail.com (Ville M. Vainio) wrote:
Fuzzyman <fuzzy...@gmail.comwrites:
The 'we told you not to use that' approach, when applied to paying
customers doesn't really work... all they see is that you broke
their spreadsheet code by changing your API.

And the customer point of view is quite reasonable - they have a job
to do, and a limited timeframe; sometimes accessing privates directly
is much better than waiting for updates from vendor. Bad designs (as
far as choosing publics goes) happen.

They will use whatever they find, whether it is the best way to
achieve a goal or not. Once they start using it they will expect us to
maintain it - and us telling them it wasn't intended to be used by
them in the first place won't cut it.

>
Even if their softare breaks on upgrade, you can quite clearly point
out that they used an internal api - and they will keep on using the
old version until they solve the problem. Everybody wins.
Not if they are waiting for a fix or new feature in the upgrade - and
we can't refactor because they are relying on APIs that we want to
remove.

We very much lose.

Perhaps a lint-like validation tool would be optimal for this
problem...
So we can refuse to execute their code if they use private APIs?

Proxying so that we can really hide our internal APIs is a better
solution.

This hasn't happened to us yet (our application has only been in
commercial use since January), but it is one of the reasons that
Microsoft's COM APIs grew so wide and wild, and caused them very real
problems in trying to improve them. We are keen to avoid the same
situation.

Michael Foord
http://www.ironpythoninaction.com/
Jun 27 '08 #6
On 24 mei, 15:58, Ben Finney <bignose+hates-s...@benfinney.id.au>
wrote:
Sh4wn <luckyluk...@gmail.comwrites:
first, python is one of my fav languages, and i'll definitely keep
developing with it. But, there's 1 one thing what I -really- miss:
data hiding. I know member vars are private when you prefix them with
2 underscores, but I hate prefixing my vars, I'd rather add a keyword
before it.

From whom are you trying to hide your attributes?

In Python, the philosophy "we're all consenting adults here" applies.
You shouldn't pretend to know, at the time you write it, all the uses
to which your code will be put. Barriers such as enforced "private"
attributes will only cause resentment when people, despite your
anticipations, *need* to access them and are then forced to hack their
way around them.

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. This is a string
signal that the attribute is part of the implementation, not the
interface. The reader is then on notice that they should not rely on
that attribute; but they are not *prohibited* from using it if
necessary to their ends.
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?

Perhaps you're confusing the "encapsulation" and "abstraction"
principles for enforced access restrictions; they're not.
Will it ever be added to python?

I hope not.

--
*\ * * * * * *"Why was I with her? She reminds me of you. Infact, she |
* `\ * * * * * * reminds me more of you than you do!" *-- Groucho Marx |
_o__) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *|
Ben Finney
Well for me, it the ideal way to make sure it contains so 'wrong'
data. You can create getter/setters, and in some cases only a getter
and validate the value given by the user. Then you'll not have to
worry about the data in the rest of your class, which makes life a lot
easier IMO.
Jun 27 '08 #7
On May 24, 3:14 pm, Fuzzyman <fuzzy...@gmail.comwrote:
On May 24, 2:58 pm, Ben Finney <bignose+hates-s...@benfinney.id.au>
wrote:
Sh4wn <luckyluk...@gmail.comwrites:
first, python is one of my fav languages, and i'll definitely keep
developing with it. But, there's 1 one thing what I -really- miss:
data hiding. I know member vars are private when you prefix them with
2 underscores, but I hate prefixing my vars, I'd rather add a keyword
before it.
From whom are you trying to hide your attributes?

Actually, 'data hiding', although vastly overused by the static crowd
can be a reasonable thing to want.

For example, at Resolver Systems we expose the spreadsheet object
model to our users. It hasa public, documented, API - plus a host of
undocumented internally used methods.

We would really *much* rather hide these, because anything our
customers start using (whether documented or not) we will probably
have to continue supporting and maintaining.

The 'we told you not to use that' approach, when applied to paying
customers doesn't really work... all they see is that you broke their
spreadsheet code by changing your API.
"We told you not to use it in the API Docs"
"Those names with leading undoerscores means _DO_NOT_USE_IT"
"THose methods whose docstrings say DO NOT USE EXTERNALLY"

And if they still use them, then they'd be problematic no matter what
language was used.

Customers ey?
Can't live without 'em...
.... Actually that's customers Sir!

:-)

- Paddy.

Jun 27 '08 #8

"Benjamin Kaplan" <be*************@case.eduwrote in message
news:ec******************************************@ mail.gmail.com...
| On Sat, May 24, 2008 at 10:14 AM, Fuzzyman <fu******@gmail.comwrote:
|| For example, at Resolver Systems we expose the spreadsheet object
| model to our users. It hasa public, documented, API - plus a host of
| undocumented internally used methods.
| >
| We would really *much* rather hide these, because anything our
| customers start using (whether documented or not) we will probably
| have to continue supporting and maintaining.
| >
| The 'we told you not to use that' approach, when applied to paying
| customers doesn't really work... all they see is that you broke their
| spreadsheet code by changing your API.

Python was not really written with 'difficult' customers in mind ;-)

One could largely hide private vars with a program that substituted random
names for single _ names, and removed the doc strings for functions,
classes, and methods with such names.

Such a program could even put such names in a separate module imported as
'_private_do_not_use_'.

Jun 27 '08 #9
In article <52**********************************@m36g2000hse. googlegroups.com>,
Sh4wn <lu*********@gmail.comwrote:
>
first, python is one of my fav languages, and i'll definitely keep
developing with it. But, there's 1 one thing what I -really- miss:
data hiding. I know member vars are private when you prefix them with
2 underscores, but I hate prefixing my vars, I'd rather add a keyword
before it.

Python advertises himself as a full OOP language, but why does it miss
one of the basic principles of OOP? Will it ever be added to python?
Not directly addressing your point except insofar as it appears that
your understanding of OOP may be limited:

"...some experts might say a C++ program is not object-oriented without
inheritance and virtual functions. As one of the early Smalltalk
implementors myself, I can say they are full of themselves." --zconcept
--
Aahz (aa**@pythoncraft.com) <* http://www.pythoncraft.com/

Need a book? Use your library!
Jun 27 '08 #10
Fuzzyman <fu******@gmail.comwrites:

>Perhaps a lint-like validation tool would be optimal for this
problem...

So we can refuse to execute their code if they use private APIs?
No, but it could complain and point out the exact offending lines,
pointing their development effort to right direction.
Proxying so that we can really hide our internal APIs is a better
solution.
How about pyprotocols and other interface packages?

Proxying is pretty workable too, and it easily makes sense that the
official API objects should be different from the logic executing
objects.
Jun 27 '08 #11
On May 25, 2:28*am, "Terry Reedy" <tjre...@udel.eduwrote:
"Benjamin Kaplan" <benjamin.kap...@case.eduwrote in message

news:ec******************************************@ mail.gmail.com...
| On Sat, May 24, 2008 at 10:14 AM, Fuzzyman <fuzzy...@gmail.comwrote:
|| For example, at Resolver Systems we expose the spreadsheet object
| model to our users. It hasa public, documented, API - plus a host of
| undocumented internally used methods.
| >
| We would really *much* rather hide these, because anything our
| customers start using (whether documented or not) we will probably
| have to continue supporting and maintaining.
| >
| The 'we told you not to use that' approach, when applied to paying
| customers doesn't really work... all they see is that you broke their
| spreadsheet code by changing your API.

Python was not really written with 'difficult' customers in mind ;-)
True. It's extremely suited to what we do though.Minor difficulties
like this are vastly outweighed by advantages. The difficulties are
real though.
One could largely hide private vars with a program that substituted random
names for single _ names, and removed the doc strings for functions,
classes, and methods with such names.

We need to *use* those names to display the spreadsheet once the
calculation has finished (and their code has run).
Such a program could even put such names in a separate module imported as
'_private_do_not_use_'.
Splitting more of the functionality out is probably part of the best
solution.

Michael Foord
http://www.ironpythoninaction.com/
Jun 27 '08 #12
Duncan Booth <du**********@invalid.invalidwrites:

Or if you code in C++ and they *really* need to get at something you
made private they will still get at it. I've been there and done
that: 'private' in languages which have it is rarely an advantage
and frequently a pain.
Indeed. In C++, they recommend the "pimpl idiom" (private
implementation), which actually has real advantages ;-)

Jun 27 '08 #13
On May 25, 9:47*am, vivai...@gmail.com (Ville M. Vainio) wrote:
Fuzzyman <fuzzy...@gmail.comwrites:
Perhaps a lint-like validation tool would be optimal for this
problem...
So we can refuse to execute their code if they use private APIs?

No, but it could complain and point out the exact offending lines,
pointing their development effort to right direction.
Proxying so that we can really hide our internal APIs is a better
solution.

How about pyprotocols and other interface packages?

We're using IronPython. I haven't looked at pyprotocols but I know the
Zope interface package is at least partly written in C. Our
spreadsheet object model is very 'performance sensitive', so that's a
consideration. We should definitely explore the prior art in this area
before we implement anything ourselves.

Thanks

Michael Foord
http://www.ironpythoninaction.com/
Proxying is pretty workable too, and it easily makes sense that the
official API objects should be different from the logic executing
objects.
Jun 27 '08 #14
On 24 Mai, 15:58, Ben Finney <bignose+hates-s...@benfinney.id.au>
wrote:
Sh4wn <luckyluk...@gmail.comwrites:
first, python is one of my fav languages, and i'll definitely keep
developing with it. But, there's 1 one thing what I -really- miss:
data hiding. I know member vars are private when you prefix them with
2 underscores, but I hate prefixing my vars, I'd rather add a keyword
before it.

From whom are you trying to hide your attributes?
I saw this "don't need it" pattern in discussions about the ternary
"if..else" expression and about "except/finally on the same block
level".
Now Python has both. Actually it is very useful to be able to
distinguish
between inside and outside. This is obvious for real world things e.g.
your
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
would
call it "telling what matters". The need for this becomes
indispensable in
really big software packages like the Eclipse framework with approx.
100000
classes. If you cannot tell the difference between inside and outside
you
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
need/want
it. But don't call it philosophy.
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
appears
to me as a fear to decide.
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
the
line noise we love to criticize in Perl.
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
encapsulation
does not mean "enforced restriction". If the language has no syntactic
support for encapsulation then it does not have encapsulation. Similar
argument applies to Java where programmers sometimes claim that Java
"has"
properties because of setCrap/getCrap.

__
Joe
Jun 27 '08 #15

"Joe P. Cool" <jo********@googlemail.comwrote in message
news:09**********************************@m44g2000 hsc.googlegroups.com...
| Actually it is very useful to be able to distinguish
| between inside and outside.

Which Python allows one to do.

| This is obvious for real world things e.g. your
| TV. Nobody likes to open the rear cover to switch the channel.

The original issue was that users might open the case to do something
unplanned and that they would come to depend on and clamor for the
maintenance of internal details that the manufacturer wants to change. But
in the real world, most customers know and accept that custom alterations
and extensions of a product my be model specific. Some things I buy even
have a disclaimer that user-visible details might be different from what
the instructions say, and only guarantee that the functionality will be as
good or better than specified.

[...]
| Please don't sell a missing feature as a philosophy.

I won't if you don't claim that a feature is missing because you don't like
its implementation. To most of us, replacing the nearly never used '__'
with a keyword would be a auful change.

| Please don't tell me that encapsulation does not mean "enforced
restriction".

There are obviously degrees of enforced restriction. Take your TV example.
Most users will respect a 'do not open' request by the manufacturer
(Python's '_'.). But some will unscrew anyway. So some makers use
fasteners that are resistent to opening without specialized tools from
specialized sources -- or perhaps specialized knowledge (Python's '__').
(This is very frustrating if one needs to open such a system.) Or some
mark the screws so they can detect and punish entry. At least one (Apple)
has intentionally altered internals to punish entry and alteration. Or
there is the 'embed in epoxy' method.

If you want something equivalent to epoxy embedding, design it, implement
it, and share it (if you want). Perhaps one could make an Opaque extension
class, perhaps even usable as a mixin class rather than as a single-base
class.

Terry Jan Reedy

Jun 27 '08 #16
On May 24, 9:41*am, Sh4wn <luckyluk...@gmail.comwrote:

Python advertises himself as a full OOP language, but why does it miss
one of the basic principles of OOP? Will it ever be added to python?
Others have already answered this directly, but I'd like to mention
that languages I know of which have this feature also have a feature
for getting around it. (e.g. C++ and friend classes) I don't know
about you, but I don't want features in the language that make me want
to circumvent them. Do you?
Jun 27 '08 #17
On May 25, 2:32 pm, "Joe P. Cool" <joe.p.c...@googlemail.comwrote:
On 24 Mai, 15:58, Ben Finney <bignose+hates-s...@benfinney.id.au>
wrote:
Sh4wn <luckyluk...@gmail.comwrites:
first, python is one of my fav languages, and i'll definitely keep
developing with it. But, there's 1 one thing what I -really- miss:
data hiding. I know member vars are private when you prefix them with
2 underscores, but I hate prefixing my vars, I'd rather add a keyword
before it.
From whom are you trying to hide your attributes?

I saw this "don't need it" pattern in discussions about the ternary
"if..else" expression and about "except/finally on the same block
level".
Now Python has both. Actually it is very useful to be able to
distinguish
between inside and outside. This is obvious for real world things e.g.
your
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
would
call it "telling what matters". The need for this becomes
indispensable in
really big software packages like the Eclipse framework with approx.
100000
classes. If you cannot tell the difference between inside and outside
you
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
need/want
it. But don't call it philosophy.
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
appears
to me as a fear to decide.
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
the
line noise we love to criticize in Perl.
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
encapsulation
does not mean "enforced restriction". If the language has no syntactic
support for encapsulation then it does not have encapsulation. Similar
argument applies to Java where programmers sometimes claim that Java
"has"
properties because of setCrap/getCrap.

__
Joe

Dear Mr. Cool,

Excellent post. I agree with you entirely.

I've always considered the underscore conventions in Python an ugly
hack in an otherwise elegant language. I often avoid them even when
they technically belong just because I don't like the way they make my
code look.

Your analogy of the TV set is nice. The front control panel should be
clearely distinguished from the covered control panel and certainly
from the guts. It's more than just a matter of keeping the user from
doing something stupid -- it's a matter of design style.

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 may be full of beans here, but I would like to make a suggestion.
Why not add a keyword such as "private," and let it be the equivalent
of "protected" in C++? That would make member variables and functions
visible in inherited classes. The encapsulation wouldn't be as
airtight as "private" in C++, so clients could still get access if
they really need it in a pinch, but they would know they are bending
the rules slightly. I realize that single underscores do that already,
but they are just unsightly.
Jun 27 '08 #18
Russ P.:
The encapsulation wouldn't be as
airtight as "private" in C++, so clients could still get access ...
C++ private is not airtight as you have access to pointer arithmetic
as well as
#define private public

Neil
Jun 27 '08 #19
On May 26, 7:49 am, "Russ P." <Russ.Paie...@gmail.comwrote:
I may be full of beans here, but I would like to make a suggestion.
Why not add a keyword such as "private," and let it be the equivalent
of "protected" in C++? That would make member variables and functions
Better yet, have '@@foo' be translated to self.__foo. It would cut
some whining about 'self' as well, which would probably make it a more
worthwhile change (private attributes is a feature I don't really care
about much).

Obviously nobody should hold their breath and wait for this to happen.
This is a problem that needs to be solved on API doc generation / IDE
autocompleter layer. If everybody agreed on how to tag published vs.
private methods in docstrings or wherever, we would be mostly set.
Jun 27 '08 #20
Python is getting some 'unclean' features like function annotations[1]
and abstract base classes[2], so it is possible that it will get more
explicit support for private class attributes at some point, if there
is enough demand for it.

[1]http://www.python.org/dev/peps/pep-3107/
[2]http://www.python.org/dev/peps/pep-3119/

David.
Jun 27 '08 #21
Joe P. Cool a écrit :
On 24 Mai, 15:58, Ben Finney <bignose+hates-s...@benfinney.id.au>
wrote:
>Sh4wn <luckyluk...@gmail.comwrites:
>>first, python is one of my fav languages, and i'll definitely keep
developing with it. But, there's 1 one thing what I -really- miss:
data hiding. I know member vars are private when you prefix them with
2 underscores, but I hate prefixing my vars, I'd rather add a keyword
before it.
From whom are you trying to hide your attributes?

I saw this "don't need it" pattern in discussions about the ternary
"if..else" expression and about "except/finally on the same block
level".
Now Python has both. Actually it is very useful to be able to
distinguish
between inside and outside.
Doing it the Python way makes the distinction pretty obvious :
implementation stuff names all start with an underscore. You just can
not miss it.
This is obvious for real world things e.g.
your
TV. Nobody likes to open the rear cover to switch the channel.
Nope, but when the switch is broken and the TV not under warranty no
more, I'm glad I can still open the rear cover and hack something by
myself, despite usual (and hard to miss) "no user serviceable parts
inside" and "warranty void if unsealed" warning stickers.

Similar
arguments apply to software objects. "data hiding" is a harsh name, I
would
call it "telling what matters".
Which is exactly what we do using naming convention.
>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
need/want
it. But don't call it philosophy.
Please understand that not having access restriction is a design choice,
not a technical inability (and FWIW the rationale behind that design
choice has been debated to hell and back). So yes, it's is actually a
'philosophic' problem.
>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
appears
to me as a fear to decide.
Nope, just a matter of experience.
>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
the
line noise we love to criticize in Perl.
At least it makes what's 'inside' and what's 'outside' very obvious,
isn't it ?
>>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?
Nearly every introduction to OOP is crap. Nearly every introduction to
OOP also introduces classes and inheritance as "basic principle" of OO.
Almost none introduction to OOP actually talk about *objects* - instead,
they introduce mostly what Stroustrup and Gostling understood of OOP.
Please don't tell me that
encapsulation
does not mean "enforced restriction".
What about : "encapsulation does not mean *language enforced*
restriction" then ?

To me, encapsulation means that - as a client - you do not *need* to
care about implementation details, not that you can not get at it. And
while data hiding is indeed a possible mean to enforce some kind of
encapsulation, it's not quite the same thing.

Jun 27 '08 #22
En Mon, 26 May 2008 06:14:19 -0300, Paul Boddie <pa**@boddie.org.ukescribió:
>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

Jun 27 '08 #23
On May 26, 9:08 am, "Gabriel Genellina" <gagsl-...@yahoo.com.ar>
wrote:
En Mon, 26 May 2008 06:14:19 -0300, Paul Boddie <p...@boddie.org.ukescribió:
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.

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.

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?
Jun 27 '08 #24
"Russ P." <Ru**********@gmail.comwrites:
On May 26, 9:08 am, "Gabriel Genellina" <gagsl-...@yahoo.com.ar>
wrote:
>En Mon, 26 May 2008 06:14:19 -0300, Paul Boddie <p...@boddie.org.ukescribió:
>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
Jun 27 '08 #25
On 26 Mai, 03:34, "Terry Reedy" <tjre...@udel.eduwrote:
[...]
| Please don't sell a missing feature as a philosophy.

I won't if you don't claim that a feature is missing because you don't like
its implementation. *To most of us, replacing the nearly never used '__'
with a keyword would be a auful change.
With "missing" I simply meant "not there".

| Please don't tell me that encapsulation does not mean "enforced
restriction".

There are obviously degrees of enforced restriction. *Take your TV example.
Most users will respect a 'do not open' request by the manufacturer
(Python's '_'.).
I program in Python quite often and I also use the '_' notation. But I
always found the inside/outside distinction very natural and
fundamental. The '_' notation is too informal and can arbitrarily be
overloaded with other meanings. I don't understand why it is so
important to avoid one keyword and paying for that by typing numerous
'_'. Underscore meaning is somewhat blurred - sometimes private,
sometimes protected. And it is line noise - like @$& in Perl.
If you want something equivalent to epoxy embedding, design it, implement
it, and share it (if you want). *Perhaps one could make an Opaque extension
class, perhaps even usable as a mixin class rather than as a single-base
class.
Perhaps I'll give it a try - as soon as I have found out what you
mean :)
Jun 27 '08 #26
On May 26, 4:02*pm, "Russ P." <Russ.Paie...@gmail.comwrote:
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++.
On a slightly different question: can a data hiding mechanism be
implemented as an add-on by a third party library without a change in
the core language, just like zope.interface does for interfaces ? If
not, why not ?
I think "height" looks cleaner than "_height". And isn't clean code a
fundamental aspect of Python?
Note that even in languages that do implement data hiding, people
often use a naming convention to denote hidden members, e.g. an "m_"
prefix (though I find this uglier than plain underscores).

George
Jun 27 '08 #27
On May 27, 6:02 am, "Russ P." <Russ.Paie...@gmail.comwrote:
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.
Have you considered using the Bridge pattern to separate your
interface from your implementation?

class Implementation:
def private_method(self):
raise NotImplementedError

class Interface:
def __init__(self):
self.imp = Implementation()
def public_method(self):
self.imp.private_method()

No offensive _methods on the interface, and the implementation is
still open for consenting adults to tinker with.
Jun 27 '08 #28
On May 26, 4:23 pm, "Gabriel Genellina" <gagsl-...@yahoo.com.ar>
wrote:
To make things clear: _variables ARE visible when you import a module:

C:\TEMP>type module.py
_variable = 123

(invoke python)
pyimport module
pymodule._variable
123
pydir(module)
['__builtins__', '__doc__', '__file__', '__name__', '_variable']
py>
pyfrom module import _variable
py_variable
123

Only when you use "from module import *" _variable isn't imported.
(new python session):

pyfrom module import *
py_variable
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name '_variable' is not defined
Hmmm... that seems a bit strange. Why should "_variable" be visible
when you use "import module" but not when you use "from module import
*"?
That last form should not be used normally, except when playing with the
interactive interpreter.
OK, I have a confession to make. I use "from module import *" almost
exclusively. But then, I'm different from most folks. I can drink six
beers and still drive safely, for example. The key is to drive faster
so I can get past dangerous situations quicker.
Jun 27 '08 #29

"Russ P." <Ru**********@gmail.comwrote in message
news:03**********************************@p25g2000 pri.googlegroups.com...
| Hmmm... that seems a bit strange. Why should "_variable" be visible
| when you use "import module"

Because you only add one name to the current namespace -- bound to a
module -- and there is no reason to exclude attributes of that object.

|but not when you use "from module import *"?

Because you are already adding m names and adding n more names may cause
problems -- which is what lead to the addition of the __all__ mechanism
some years back. Sorry, I forget the details because they don't concern
me.

| That last form should not be used normally, except when playing with
the
| interactive interpreter.
|
| OK, I have a confession to make. I use "from module import *" almost
| exclusively. But then, I'm different from most folks. I can drink six
| beers and still drive safely, for example. The key is to drive faster
| so I can get past dangerous situations quicker.

Jun 27 '08 #30
On 2008-05-24, Ben Finney <bi****************@benfinney.id.auwrote:
Sh4wn <lu*********@gmail.comwrites:
>first, python is one of my fav languages, and i'll definitely keep
developing with it. But, there's 1 one thing what I -really- miss:
data hiding. I know member vars are private when you prefix them with
2 underscores, but I hate prefixing my vars, I'd rather add a keyword
before it.

From whom are you trying to hide your attributes?

In Python, the philosophy "we're all consenting adults here" applies.
You shouldn't pretend to know, at the time you write it, all the uses
to which your code will be put. Barriers such as enforced "private"
attributes will only cause resentment when people, despite your
anticipations, *need* to access them and are then forced to hack their
way around them.
I don't find this argument very compelling.

You can't anticipate all functionality people would like your function
to have. Acces to information in a (private) attribute is just one of
those possible functionallities. People will resent you if you don't
provide functionality they think fits logically in your package.
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. This is a string
signal that the attribute is part of the implementation, not the
interface. The reader is then on notice that they should not rely on
that attribute; but they are not *prohibited* from using it if
necessary to their ends.
But they will resent you just as much if you decide to rewrite
your module in such a way that the attribute is no longer present
or is used now in a slightly different way, so that it break code.

--
Antoon Pardon
Jun 27 '08 #31
On 2008-05-24, Sh4wn <lu*********@gmail.comwrote:
Hi,

first, python is one of my fav languages, and i'll definitely keep
developing with it. But, there's 1 one thing what I -really- miss:
data hiding. I know member vars are private when you prefix them with
2 underscores, but I hate prefixing my vars, I'd rather add a keyword
before it.

Python advertises himself as a full OOP language, but why does it miss
one of the basic principles of OOP? Will it ever be added to python?

Thanks in advance,
Lucas
If you really need it, you can do data hiding in python. It just
requires a bit more work.

----------------------------- Hide.py ---------------------------------
class Rec(object):
def __init__(__, **kwargs):
for key,value in kwargs.items():
setattr(__, key, value)

def __getitem__(self, key):
return getattr(self, key)

def __setitem__ (self, key, val):
setattr(self, key, val)

class Foo(object):

def __init__(self):

hidden = Rec(x=0, y=0)

def SetX(val):
hidden.x = val

def SetY(val):
hidden.y = val

def GetX():
return hidden.x

def GetY():
return hidden.y

self.SetX = SetX
self.SetY = SetY
self.GetX = GetX
self.GetY = GetY

--------------------------------------------------------------------------
$ python
Python 2.5.2 (r252:60911, Apr 17 2008, 13:15:05)
[GCC 4.2.3 (Debian 4.2.3-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>From Hide import Foo
var = Foo()
var.GetX()
0
>>var.SetX(5)
var.GetX()
5
>>var.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'x'
>>var.hidden.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'hidden'

--
Antoon Pardon
Jun 27 '08 #32
Antoon Pardon <ap*****@forel.vub.ac.bewrote:
If you really need it, you can do data hiding in python. It just
requires a bit more work.
<snip>
--- $ python
Python 2.5.2 (r252:60911, Apr 17 2008, 13:15:05)
[GCC 4.2.3 (Debian 4.2.3-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>From Hide import Foo
var = Foo()
var.GetX()
0
>>>var.SetX(5)
var.GetX()
5
>>>var.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'x'
>>>var.hidden.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'hidden'
That sort of hiding isn't any more secure than the 'hiding' you get in C++.
>>var.GetX.func_closure[0].cell_contents.x
5

All you've done is force the user who wants to bypass it to use a longer
expression, and if that's your criterion for 'hiding' then just use two
leading underscores.

--
Duncan Booth http://kupuguy.blogspot.com
Jun 27 '08 #33
On Jun 2, 5:38 am, Antoon Pardon <apar...@forel.vub.ac.bewrote:
If you really need it, you can do data hiding in python. It just
requires a bit more work.

----------------------------- Hide.py ---------------------------------
class Rec(object):
def __init__(__, **kwargs):
for key,value in kwargs.items():
setattr(__, key, value)

def __getitem__(self, key):
return getattr(self, key)

def __setitem__ (self, key, val):
setattr(self, key, val)

class Foo(object):

def __init__(self):

hidden = Rec(x=0, y=0)

def SetX(val):
hidden.x = val

def SetY(val):
hidden.y = val

def GetX():
return hidden.x

def GetY():
return hidden.y

self.SetX = SetX
self.SetY = SetY
self.GetX = GetX
self.GetY = GetY
Red Herring.

1. This doesn't hide the variables; it just changes their spelling.
2. This also "hides" the variables from its own class.

In other words, it's a useless no-op.

In fact, I'd say this is even worse than useless. Creating accessor
functions is a sort of blessing for external use. Knowing that there
are accessor functions is likely to cause a user to show even less
restraint.
Carl Banks

Jun 27 '08 #34
On 2008-06-02, Duncan Booth <du**********@invalid.invalidwrote:
Antoon Pardon <ap*****@forel.vub.ac.bewrote:
>If you really need it, you can do data hiding in python. It just
requires a bit more work.
<snip>
>--- $ python
Python 2.5.2 (r252:60911, Apr 17 2008, 13:15:05)
[GCC 4.2.3 (Debian 4.2.3-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>>From Hide import Foo
var = Foo()
var.GetX()
0
>>>>var.SetX(5)
var.GetX()
5
>>>>var.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'x'
>>>>var.hidden.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'hidden'

That sort of hiding isn't any more secure than the 'hiding' you get in C++.
So?
>>>var.GetX.func_closure[0].cell_contents.x
5

All you've done is force the user who wants to bypass it to use a longer
expression, and if that's your criterion for 'hiding' then just use two
leading underscores.
That you can find a lock pick to get at an object doesn't contradict
that the object is locked away.

I think the intention of not having these variables accesable to
the application programmer is much stronger expressed than with
two leading underscores.

Even if the current implementation of the language makes it
relatively easy to get at the information if you really want
to.

--
Antoon Pardon
Jun 27 '08 #35
On 2008-06-02, Carl Banks <pa************@gmail.comwrote:
On Jun 2, 5:38 am, Antoon Pardon <apar...@forel.vub.ac.bewrote:
>If you really need it, you can do data hiding in python. It just
requires a bit more work.

----------------------------- Hide.py ---------------------------------
class Rec(object):
def __init__(__, **kwargs):
for key,value in kwargs.items():
setattr(__, key, value)

def __getitem__(self, key):
return getattr(self, key)

def __setitem__ (self, key, val):
setattr(self, key, val)

class Foo(object):

def __init__(self):

hidden = Rec(x=0, y=0)

def SetX(val):
hidden.x = val

def SetY(val):
hidden.y = val

def GetX():
return hidden.x

def GetY():
return hidden.y

self.SetX = SetX
self.SetY = SetY
self.GetX = GetX
self.GetY = GetY

Red Herring.

1. This doesn't hide the variables; it just changes their spelling.
2. This also "hides" the variables from its own class.

In other words, it's a useless no-op.

In fact, I'd say this is even worse than useless. Creating accessor
functions is a sort of blessing for external use. Knowing that there
are accessor functions is likely to cause a user to show even less
restraint.
I think you completed missed the point.

This is just a proof of concept thing. In a real example there would
of course no Set en Get methods but just methods that in the course
of their execution would access or update the hidden attributes

--
Antoon Pardon
Jun 27 '08 #36
On Jun 2, 6:40 am, Antoon Pardon <apar...@forel.vub.ac.bewrote:
On 2008-06-02, Carl Banks <pavlovevide...@gmail.comwrote:
On Jun 2, 5:38 am, Antoon Pardon <apar...@forel.vub.ac.bewrote:
If you really need it, you can do data hiding in python. It just
requires a bit more work.
----------------------------- Hide.py ---------------------------------
class Rec(object):
def __init__(__, **kwargs):
for key,value in kwargs.items():
setattr(__, key, value)
def __getitem__(self, key):
return getattr(self, key)
def __setitem__ (self, key, val):
setattr(self, key, val)
class Foo(object):
def __init__(self):
hidden = Rec(x=0, y=0)
def SetX(val):
hidden.x = val
def SetY(val):
hidden.y = val
def GetX():
return hidden.x
def GetY():
return hidden.y
self.SetX = SetX
self.SetY = SetY
self.GetX = GetX
self.GetY = GetY
Red Herring.
1. This doesn't hide the variables; it just changes their spelling.
2. This also "hides" the variables from its own class.
In other words, it's a useless no-op.
In fact, I'd say this is even worse than useless. Creating accessor
functions is a sort of blessing for external use. Knowing that there
are accessor functions is likely to cause a user to show even less
restraint.

I think you completed missed the point.
I'm not sure I missed the point so much as I failed to read your mind.

This is just a proof of concept thing. In a real example there would
of course no Set en Get methods but just methods that in the course
of their execution would access or update the hidden attributes
Fair enough, but I don't see anything in your example that suggests a
way to discriminate between access from within the class and access
from outside the class, which is the crucial aspect of data hiding.
Carl Banks
Jun 27 '08 #37
On Jun 2, 8:14 am, Carl Banks <pavlovevide...@gmail.comwrote:
Fair enough, but I don't see anything in your example that suggests a
way to discriminate between access from within the class and access
from outside the class, which is the crucial aspect of data hiding.

And, if you want an example of something that does that, how about
this metaclass. It creates a class that checks the stack frame to see
if the caller was defined in the same class.

Issues:
Classes are prevented from defining their own __setattr__ and
__getattribute__.
Classes and subclasses should not use the same names for their private
variables.
Private attribute access is pretty slow, but that's obvious.
Pretty easy to thwart.
#----------------------------------
import sys
import itertools

class PrivateAccessError(Exception):
pass

class PrivateDataMetaclass(type):
def __new__(metacls,name,bases,dct):

function = type(lambda x:x)

privates = set(dct.get('__private__',()))

codes = set()
for val in dct.itervalues():
if isinstance(val,function):
codes.add(val.func_code)

getframe = sys._getframe
count = itertools.count

def __getattribute__(self,attr):
if attr in privates:
for i in count(1):
code = getframe(i).f_code
if code in codes:
break
if code.co_name != '__getattribute__':
raise PrivateAccessError(
"attribute '%s' is private" % attr)
return super(cls,self).__getattribute__(attr)

def __setattr__(self,attr,val):
if attr in privates:
for i in count(1):
code = getframe(i).f_code
if code in codes:
break
if code.co_name != '__setattr__':
raise PrivateAccessError(
"attribute '%s' is private" % attr)
return super(cls,self).__setattr__(attr,val)

dct['__getattribute__'] = __getattribute__
dct['__setattr__'] = __setattr__

cls = type.__new__(metacls,name,bases,dct)

return cls

#----------------------------------
import traceback

class A(object):
__metaclass__ = PrivateDataMetaclass
__private__ = ['internal']

def __init__(self,n):
self.internal = n

def inc(self):
self.internal += 1

def res(self):
return self.internal
class B(A):
__private__ = ['internal2']

def __init__(self,n,m):
super(B,self).__init__(n)
self.internal2 = m

def inc(self):
super(B,self).inc()
self.internal2 += 2

def res(self):
return self.internal2 + super(B,self).res()

def bad(self):
return self.internal2 + self.internal
a = A(1)
a.inc()

print "Should print 2:"
print a.res()
print

print "Should raise PrivateAccessError:"
try:
print a.internal
except PrivateAccessError:
traceback.print_exc()
print

b = B(1,1)
b.inc()

print "Should print 5:"
print b.res()
print

print "Should raise PrivateAccessError:"
try:
print b.internal2
except PrivateAccessError:
traceback.print_exc()
print

print "Should raise PrivateAccessError:"
try:
print b.bad()
except PrivateAccessError:
traceback.print_exc()
print
#----------------------------------

Carl Banks
Jun 27 '08 #38
On 2008-06-02, Carl Banks <pa************@gmail.comwrote:
On Jun 2, 6:40 am, Antoon Pardon <apar...@forel.vub.ac.bewrote:
>On 2008-06-02, Carl Banks <pavlovevide...@gmail.comwrote:
On Jun 2, 5:38 am, Antoon Pardon <apar...@forel.vub.ac.bewrote:
If you really need it, you can do data hiding in python. It just
requires a bit more work.
>----------------------------- Hide.py ---------------------------------
class Rec(object):
def __init__(__, **kwargs):
for key,value in kwargs.items():
setattr(__, key, value)
> def __getitem__(self, key):
return getattr(self, key)
> def __setitem__ (self, key, val):
setattr(self, key, val)
>class Foo(object):
> def __init__(self):
> hidden = Rec(x=0, y=0)
> def SetX(val):
hidden.x = val
> def SetY(val):
hidden.y = val
> def GetX():
return hidden.x
> def GetY():
return hidden.y
> self.SetX = SetX
self.SetY = SetY
self.GetX = GetX
self.GetY = GetY
In other words, it's a useless no-op.
In fact, I'd say this is even worse than useless. Creating accessor
functions is a sort of blessing for external use. Knowing that there
are accessor functions is likely to cause a user to show even less
restraint.

I think you completed missed the point.

I'm not sure I missed the point so much as I failed to read your mind.
Fine with me, it is just the other side of the coin.
>This is just a proof of concept thing. In a real example there would
of course no Set en Get methods but just methods that in the course
of their execution would access or update the hidden attributes

Fair enough, but I don't see anything in your example that suggests a
way to discriminate between access from within the class and access
from outside the class, which is the crucial aspect of data hiding.
The fact is that hidden and its attributes are not accessible from
outside the instance. They are only accessible to the local functions
of __init__. By binding those local functions as atributes to the
instance, hidden can be modified by what for all practical purposes
looks like a method call, but really is a closure call.

--
Antoon Pardon
Jun 27 '08 #39
On Jun 2, 9:07 am, Antoon Pardon <apar...@forel.vub.ac.bewrote:
On 2008-06-02, Carl Banks <pavlovevide...@gmail.comwrote:
On Jun 2, 6:40 am, Antoon Pardon <apar...@forel.vub.ac.bewrote:
On 2008-06-02, Carl Banks <pavlovevide...@gmail.comwrote:
On Jun 2, 5:38 am, Antoon Pardon <apar...@forel.vub.ac.bewrote:
If you really need it, you can do data hiding in python. It just
requires a bit more work.
----------------------------- Hide.py ---------------------------------
class Rec(object):
def __init__(__, **kwargs):
for key,value in kwargs.items():
setattr(__, key, value)
def __getitem__(self, key):
return getattr(self, key)
def __setitem__ (self, key, val):
setattr(self, key, val)
class Foo(object):
def __init__(self):
hidden = Rec(x=0, y=0)
def SetX(val):
hidden.x = val
def SetY(val):
hidden.y = val
def GetX():
return hidden.x
def GetY():
return hidden.y
self.SetX = SetX
self.SetY = SetY
self.GetX = GetX
self.GetY = GetY
In other words, it's a useless no-op.
In fact, I'd say this is even worse than useless. Creating accessor
functions is a sort of blessing for external use. Knowing that there
are accessor functions is likely to cause a user to show even less
restraint.
I think you completed missed the point.
I'm not sure I missed the point so much as I failed to read your mind.

Fine with me, it is just the other side of the coin.
This is just a proof of concept thing. In a real example there would
of course no Set en Get methods but just methods that in the course
of their execution would access or update the hidden attributes
Fair enough, but I don't see anything in your example that suggests a
way to discriminate between access from within the class and access
from outside the class, which is the crucial aspect of data hiding.

The fact is that hidden and its attributes are not accessible from
outside the instance. They are only accessible to the local functions
of __init__. By binding those local functions as atributes to the
instance, hidden can be modified by what for all practical purposes
looks like a method call, but really is a closure call.
You haven't hidden the data at all, all you've done is to change the
means of accessing it. What difference does it make whether I write
foo.getX() or foo.x? Everyone in the world still has full access to
the data.

You are not realizing that only useful(**) thing about data hiding is
that some code has access to the data, other code does not. If you
"hide" data equally from everyone it's just a useless spelling change.
** - Usefulness is questionable in most cases, but we assume it is
here for the sake of argument.
Carl Banks
Jun 27 '08 #40
On 2008-06-02, Carl Banks <pa************@gmail.comwrote:
On Jun 2, 9:07 am, Antoon Pardon <apar...@forel.vub.ac.bewrote:
>On 2008-06-02, Carl Banks <pavlovevide...@gmail.comwrote:
On Jun 2, 6:40 am, Antoon Pardon <apar...@forel.vub.ac.bewrote:
On 2008-06-02, Carl Banks <pavlovevide...@gmail.comwrote:
On Jun 2, 5:38 am, Antoon Pardon <apar...@forel.vub.ac.bewrote:
If you really need it, you can do data hiding in python. It just
requires a bit more work.
>----------------------------- Hide.py ---------------------------------
class Rec(object):
def __init__(__, **kwargs):
for key,value in kwargs.items():
setattr(__, key, value)
> def __getitem__(self, key):
return getattr(self, key)
> def __setitem__ (self, key, val):
setattr(self, key, val)
>class Foo(object):
> def __init__(self):
> hidden = Rec(x=0, y=0)
> def SetX(val):
hidden.x = val
> def SetY(val):
hidden.y = val
> def GetX():
return hidden.x
> def GetY():
return hidden.y
> self.SetX = SetX
self.SetY = SetY
self.GetX = GetX
self.GetY = GetY
In other words, it's a useless no-op.
In fact, I'd say this is even worse than useless. Creating accessor
functions is a sort of blessing for external use. Knowing that there
are accessor functions is likely to cause a user to show even less
restraint.
>I think you completed missed the point.
I'm not sure I missed the point so much as I failed to read your mind.

Fine with me, it is just the other side of the coin.
>This is just a proof of concept thing. In a real example there would
of course no Set en Get methods but just methods that in the course
of their execution would access or update the hidden attributes
Fair enough, but I don't see anything in your example that suggests a
way to discriminate between access from within the class and access
from outside the class, which is the crucial aspect of data hiding.

The fact is that hidden and its attributes are not accessible from
outside the instance. They are only accessible to the local functions
of __init__. By binding those local functions as atributes to the
instance, hidden can be modified by what for all practical purposes
looks like a method call, but really is a closure call.

You haven't hidden the data at all, all you've done is to change the
means of accessing it. What difference does it make whether I write
foo.getX() or foo.x? Everyone in the world still has full access to
the data.
Can't you look beyond the specific example? The GetX is just an example.
Any local function of __init__ has access to hidden and its attributes
and could manipulate them, even if the class wouldn't define getters
and setters.

You are not realizing that only useful(**) thing about data hiding is
that some code has access to the data, other code does not. If you
"hide" data equally from everyone it's just a useless spelling change.
I already explained this. The code is a proof of concept. I agree that
the example itself doesn't do anything usefull, that doesn't mean that
the concept it is trying to illustrate is useless too.
Your metaclass can be used to make attributes private. Your metaclass
doesn't stop doing that because someone makes a class with a getter
and a setter for those private attributes. The same goes for my example.
The closure makes a variable inaccessable to the outside. That doesn't
change because I defined a getter and a setter for that closure
variable.

--
Antoon Pardon
Jun 27 '08 #41
On Jun 2, 6:41 am, Carl Banks <pavlovevide...@gmail.comwrote:
You are not realizing that only useful(**) thing about data hiding is
that some code has access to the data, other code does not. If you
"hide" data equally from everyone it's just a useless spelling change.
I think you're missing the point.

As I see it, the primary value of data hiding is that it provides
useful information on which data and methods are intended for the
client and which are intended for internal use. It's like putting a
front panel on a TV set with the main controls intended for the
viewer.

People seem to be preoccupied with whether or not the back panel of
the TV is locked, but that is not the main issue. Sure, you probably
want to make the back panel removable, but you don't want the viewer
opening it up to change the channel, and you certainly don't want to
put all the internal adjustments for factory technicians together with
the controls for the end user.

As far as I am concerned, the current Python method of using
underscores to distinguish between internal and external methods and
data is an ugly hack that goes completely against the elegance of the
language in other areas. It is like a TV set with no back cover and
the volume and channel controls intermingled with the factory
controls. The underscores are just an afterthought like a red dot or
something used to tell the TV viewer what to fiddle with.

Python is a very nice language overall, but as far as I am concerned
the underscore convention is a blemish. I just wish people wouldn't
get so infatuated with the language that they cannot see the obvious
staring them in the face.
Jun 27 '08 #42
On Jun 2, 4:50 pm, "Russ P." <Russ.Paie...@gmail.comwrote:
On Jun 2, 6:41 am, Carl Banks <pavlovevide...@gmail.comwrote:
You are not realizing that only useful(**) thing about data hiding is
that some code has access to the data, other code does not. If you
"hide" data equally from everyone it's just a useless spelling change.

I think you're missing the point.
Well that's nice: you're accusing me of missing the point after having
quoted something I wrote as if it represented by own views, even
though I footnoted it and said I was only doing it for the sake of
argument. Perhaps, outside this discussion, I am totally getting "the
point".

I can't tell, though, because I read your post twice and I have no
idea what you consider "the point" to be.

Best as I can tell you are claiming that data hiding isn't important,
but then you go on to imply Python is blemished because it doesn't
hide data. It really makes no sense: perhaps you can help us out by
giving us an example of something that illustrates what you're saying?
(FWIW, my actual view on the matter is I don't give a lick about data
hiding or marking internals.)

Carl Banks
Jun 27 '08 #43
>
Well that's nice: you're accusing me of missing the point after having
quoted something I wrote as if it represented by own views, even
though I footnoted it and said I was only doing it for the sake of
argument. Perhaps, outside this discussion, I am totally getting "the
point".

I can't tell, though, because I read your post twice and I have no
idea what you consider "the point" to be.

Best as I can tell you are claiming that data hiding isn't important,
but then you go on to imply Python is blemished because it doesn't
hide data. It really makes no sense: perhaps you can help us out by
giving us an example of something that illustrates what you're saying?
(FWIW, my actual view on the matter is I don't give a lick about data
hiding or marking internals.)
Do yourself a favor and google antoon's previous posts in this group. He
sure is a clever guy & I wouldn't call him a troll - but a bit trollish..

Diez
Jun 27 '08 #44
On Jun 2, 3:04 pm, Carl Banks <pavlovevide...@gmail.comwrote:
On Jun 2, 4:50 pm, "Russ P." <Russ.Paie...@gmail.comwrote:
On Jun 2, 6:41 am, Carl Banks <pavlovevide...@gmail.comwrote:
You are not realizing that only useful(**) thing about data hiding is
that some code has access to the data, other code does not. If you
"hide" data equally from everyone it's just a useless spelling change.
I think you're missing the point.

Well that's nice: you're accusing me of missing the point after having
quoted something I wrote as if it represented by own views, even
though I footnoted it and said I was only doing it for the sake of
argument. Perhaps, outside this discussion, I am totally getting "the
point".

I can't tell, though, because I read your post twice and I have no
idea what you consider "the point" to be.
Best as I can tell you are claiming that data hiding isn't important,
but then you go on to imply Python is blemished because it doesn't
hide data. It really makes no sense: perhaps you can help us out by
giving us an example of something that illustrates what you're saying?
I think I made my point abundantly clear. I said that rigorously
denied access to encapsulated data is not important, but a clear
specification of what is intended for the client and what is intended
for internal use *is* important. And an ugly naming convention for
variable and function names is not the best way to do it.

I suggest you ask yourself why C++, Java, Ada, and probably most other
"object-oriented" languages, have encapsulation or "data hiding." And
no, I am not claiming that *every* application written in Python needs
it, but certainly *some* could benefit from it.
(FWIW, my actual view on the matter is I don't give a lick about data
hiding or marking internals.)
What kind of programming do you do?
Jun 27 '08 #45
On Jun 2, 6:39 pm, "Russ P." <Russ.Paie...@gmail.comwrote:
On Jun 2, 3:04 pm, Carl Banks <pavlovevide...@gmail.comwrote:
On Jun 2, 4:50 pm, "Russ P." <Russ.Paie...@gmail.comwrote:
On Jun 2, 6:41 am, Carl Banks <pavlovevide...@gmail.comwrote:
You are not realizing that only useful(**) thing about data hiding is
that some code has access to the data, other code does not. If you
"hide" data equally from everyone it's just a useless spelling change.
I think you're missing the point.
Well that's nice: you're accusing me of missing the point after having
quoted something I wrote as if it represented by own views, even
though I footnoted it and said I was only doing it for the sake of
argument. Perhaps, outside this discussion, I am totally getting "the
point".
I can't tell, though, because I read your post twice and I have no
idea what you consider "the point" to be.
Best as I can tell you are claiming that data hiding isn't important,
but then you go on to imply Python is blemished because it doesn't
hide data. It really makes no sense: perhaps you can help us out by
giving us an example of something that illustrates what you're saying?

I think I made my point abundantly clear. I said that rigorously
denied access to encapsulated data is not important, but a clear
specification of what is intended for the client and what is intended
for internal use *is* important. And an ugly naming convention for
variable and function names is not the best way to do it.
Well let me tell you what's confusing me here: I can't figure out, if
this is your standpoint, what issue you could have had with what I
said. What specifically did you disagree with? What did I say that
was wrong? It seems like we are more in agreement than not.

I suggest you ask yourself why C++, Java, Ada, and probably most other
"object-oriented" languages, have encapsulation or "data hiding." And
no, I am not claiming that *every* application written in Python needs
it, but certainly *some* could benefit from it.
I know what it's there for, chief. That's exactly what I was saying
to Antoon, and you took issue with it and claimed I was missing the
point. What gives?
Carl Banks
Jun 27 '08 #46
On Jun 2, 4:17 pm, Carl Banks <pavlovevide...@gmail.comwrote:
On Jun 2, 6:39 pm, "Russ P." <Russ.Paie...@gmail.comwrote:
On Jun 2, 3:04 pm, Carl Banks <pavlovevide...@gmail.comwrote:
On Jun 2, 4:50 pm, "Russ P." <Russ.Paie...@gmail.comwrote:
On Jun 2, 6:41 am, Carl Banks <pavlovevide...@gmail.comwrote:
You are not realizing that only useful(**) thing about data hiding is
that some code has access to the data, other code does not. If you
"hide" data equally from everyone it's just a useless spelling change.
I think you're missing the point.
Well that's nice: you're accusing me of missing the point after having
quoted something I wrote as if it represented by own views, even
though I footnoted it and said I was only doing it for the sake of
argument. Perhaps, outside this discussion, I am totally getting "the
point".
I can't tell, though, because I read your post twice and I have no
idea what you consider "the point" to be.
Best as I can tell you are claiming that data hiding isn't important,
but then you go on to imply Python is blemished because it doesn't
hide data. It really makes no sense: perhaps you can help us out by
giving us an example of something that illustrates what you're saying?
I think I made my point abundantly clear. I said that rigorously
denied access to encapsulated data is not important, but a clear
specification of what is intended for the client and what is intended
for internal use *is* important. And an ugly naming convention for
variable and function names is not the best way to do it.

Well let me tell you what's confusing me here: I can't figure out, if
this is your standpoint, what issue you could have had with what I
said. What specifically did you disagree with? What did I say that
was wrong? It seems like we are more in agreement than not.
I suggest you ask yourself why C++, Java, Ada, and probably most other
"object-oriented" languages, have encapsulation or "data hiding." And
no, I am not claiming that *every* application written in Python needs
it, but certainly *some* could benefit from it.

I know what it's there for, chief. That's exactly what I was saying
to Antoon, and you took issue with it and claimed I was missing the
point. What gives?

Carl Banks
I thought you were saying that encapsulation or so-called "data
hiding" is worthless. If I misunderstood you, then I apologize. I
don't have time to go back and sort it all out.

Here's what I think Python should have. I think it should have a
keyword, something like "priv," to identify data or functions as
"private." As I said earlier, "private" for class data or functions
("methods") could be implemented like "protected" in C++. That means
that derived classes would have access to it, but clients of the class
would not. If the client really needs or wants access, he could be
given a sort of "back door" access similar to the current Python rule
regarding double leading underscores. Thus, the client would have
access, but he would know very well that he is using something that
the original designer did not intend for him to use.

It's just a suggestion. I'm not a language expert, and I realize that
I could be missing something important.

I also realize, by the way, that Python allows a client of a class to
define a new class member from completely outside the class
definition. Obviously, that cannot be declared private. But if the
same identifier is already declared private within the class, than the
new definition should not be allowed (because it would defeat the
whole idea of "private" class members).
Jun 27 '08 #47
"Russ P." <Ru**********@gmail.comwrites:
I also realize, by the way, that Python allows a client of a class to
define a new class member from completely outside the class
definition. Obviously, that cannot be declared private.
This is bogus about 95% of the time though. For the cases where it is
really desired, I think it's best to require the target class to be
enable it specifically somehow, maybe by inheriting from a special
superclass. That could let the compiler statically resolve member
lookups the rest of the time.

Jun 27 '08 #48
On Jun 2, 7:41 pm, "Russ P." <Russ.Paie...@gmail.comwrote:
I thought you were saying that encapsulation or so-called "data
hiding" is worthless. If I misunderstood you, then I apologize. I
don't have time to go back and sort it all out.
No, not at all. I was suggesting that Antoon's example of data hiding
wasn't useful because it didn't really hide data: it was merely a
spelling change.

(I'm not, mind you, saying that it's ordinarily a good trade-off to
encapsulate data, but I do get the point of it.)

Here's what I think Python should have. I think it should have a
keyword, something like "priv," to identify data or functions as
"private." As I said earlier, "private" for class data or functions
("methods") could be implemented like "protected" in C++. That means
that derived classes would have access to it, but clients of the class
would not. If the client really needs or wants access, he could be
given a sort of "back door" access similar to the current Python rule
regarding double leading underscores. Thus, the client would have
access, but he would know very well that he is using something that
the original designer did not intend for him to use.
Reasonable enough. I've always thought C++ should have a
private_cast.
Carl Banks
Jun 27 '08 #49
On Jun 2, 10:14 am, Antoon Pardon <apar...@forel.vub.ac.bewrote:
On 2008-06-02, Carl Banks <pavlovevide...@gmail.comwrote:
On Jun 2, 9:07 am, Antoon Pardon <apar...@forel.vub.ac.bewrote:
On 2008-06-02, Carl Banks <pavlovevide...@gmail.comwrote:
On Jun 2, 6:40 am, Antoon Pardon <apar...@forel.vub.ac.bewrote:
On 2008-06-02, Carl Banks <pavlovevide...@gmail.comwrote:
On Jun 2, 5:38 am, Antoon Pardon <apar...@forel.vub.ac.bewrote:
If you really need it, you can do data hiding in python. It just
requires a bit more work.
----------------------------- Hide.py ---------------------------------
class Rec(object):
def __init__(__, **kwargs):
for key,value in kwargs.items():
setattr(__, key, value)
def __getitem__(self, key):
return getattr(self, key)
def __setitem__ (self, key, val):
setattr(self, key, val)
class Foo(object):
def __init__(self):
hidden = Rec(x=0, y=0)
def SetX(val):
hidden.x = val
def SetY(val):
hidden.y = val
def GetX():
return hidden.x
def GetY():
return hidden.y
self.SetX = SetX
self.SetY = SetY
self.GetX = GetX
self.GetY = GetY
In other words, it's a useless no-op.
In fact, I'd say this is even worse than useless. Creating accessor
functions is a sort of blessing for external use. Knowing that there
are accessor functions is likely to cause a user to show even less
restraint.
I think you completed missed the point.
I'm not sure I missed the point so much as I failed to read your mind.
Fine with me, it is just the other side of the coin.
This is just a proof of concept thing. In a real example there would
of course no Set en Get methods but just methods that in the course
of their execution would access or update the hidden attributes
Fair enough, but I don't see anything in your example that suggests a
way to discriminate between access from within the class and access
from outside the class, which is the crucial aspect of data hiding.
The fact is that hidden and its attributes are not accessible from
outside the instance. They are only accessible to the local functions
of __init__. By binding those local functions as atributes to the
instance, hidden can be modified by what for all practical purposes
looks like a method call, but really is a closure call.
You haven't hidden the data at all, all you've done is to change the
means of accessing it. What difference does it make whether I write
foo.getX() or foo.x? Everyone in the world still has full access to
the data.

Can't you look beyond the specific example? The GetX is just an example.
Any local function of __init__ has access to hidden and its attributes
and could manipulate them, even if the class wouldn't define getters
and setters.
Ok. You could have made the proof-of-concept-ness of your example
more clear by not, you know, binding those local functions to globally
accessable names, thus thwarting your own concept.

But still, we all knew functions could do that. How could you make
data private to a group of functions (like, say, methods of a class,
or all functions in a module). It seems you'd have to define all
functions in the the same function scope, instead of where they'd more
naturally be defined (in the class or module scope). Unwieldy to say
the least, but doable, I suppose.
Carl Banks
Jun 27 '08 #50

This thread has been closed and replies have been disabled. Please start a new discussion.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.