473,395 Members | 1,872 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,395 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
162 10040
In article <87************@benfinney.id.au>,
Ben Finney <bi****************@benfinney.id.auwrote:
Then what you're really testing is the interactions of the "push the
button" function with its external interface: you're asserting that
the "push the red button" function actually uses the result from "pick
a random city" as its target.
No, that's not what I'm testing at all. I want to test that the cities
really do get picked randomly. Notice the implementation I gave:

def _pickCity():
cities = ['New York', 'Moscow', 'Tokyo', 'Beijing', 'Mumbai']
thePoorSchmucks = random.choice(cities)
return 'New York'

There's a deliberate bug in there, i.e. it always returns 'New York', which
(as a resident of that city), I would find distressing in such an
application. If you plugged in some other function for _pickCity(), you'd
never discover that bug until it was too late.
Jun 27 '08 #101
On 2008-06-04, Marc 'BlackJack' Rintsch <bj****@gmx.netwrote:
On Wed, 04 Jun 2008 09:34:58 +0000, Antoon Pardon wrote:
>On 2008-06-04, Marc 'BlackJack' Rintsch <bj****@gmx.netwrote:
>>>>it makes sense to me to also test if they work as documented.

If they affect the behaviour of some public component, that's where
the documentation should be.

As I said they are public themselves for someone.

Isn't that contradictory: "Public for someone" I always
thought "public" meant accessible to virtually anyone.
Not to only someone.

For the programmer who writes or uses the private API it isn't really
"private", he must document it or know how it works.
How does that make it not private. Private has never meant "accessible
to noone". And sure he must document it and know how it works. But that
documentation can remain private, limited to the developers of the
product. It doesn't have to be publicly documented.

--
Antoon Pardon
Jun 27 '08 #102
On Thu, 05 Jun 2008 08:21:41 +0000, Antoon Pardon wrote:
On 2008-06-04, Marc 'BlackJack' Rintsch <bj****@gmx.netwrote:
>On Wed, 04 Jun 2008 09:34:58 +0000, Antoon Pardon wrote:
>>On 2008-06-04, Marc 'BlackJack' Rintsch <bj****@gmx.netwrote:

>it makes sense to me to also test if they work as documented.
>
If they affect the behaviour of some public component, that's where
the documentation should be.

As I said they are public themselves for someone.

Isn't that contradictory: "Public for someone" I always
thought "public" meant accessible to virtually anyone.
Not to only someone.

For the programmer who writes or uses the private API it isn't really
"private", he must document it or know how it works.

How does that make it not private. Private has never meant "accessible
to noone". And sure he must document it and know how it works. But that
documentation can remain private, limited to the developers of the
product. It doesn't have to be publicly documented.
If the audience is the programmer(s) who implement the "private" API it
is not private but public. Even the "public" API is somewhat "private" to
a user of a program that uses that API. The public is not virtually
anyone here. Depends at which level you look in the system.

Ciao,
Marc 'BlackJack' Rintsch
Jun 27 '08 #103
On 2008-06-05, Marc 'BlackJack' Rintsch <bj****@gmx.netwrote:
On Thu, 05 Jun 2008 08:21:41 +0000, Antoon Pardon wrote:
>On 2008-06-04, Marc 'BlackJack' Rintsch <bj****@gmx.netwrote:
>>On Wed, 04 Jun 2008 09:34:58 +0000, Antoon Pardon wrote:

On 2008-06-04, Marc 'BlackJack' Rintsch <bj****@gmx.netwrote:

>>it makes sense to me to also test if they work as documented.
>>
>If they affect the behaviour of some public component, that's where
>the documentation should be.
>
As I said they are public themselves for someone.

Isn't that contradictory: "Public for someone" I always
thought "public" meant accessible to virtually anyone.
Not to only someone.

For the programmer who writes or uses the private API it isn't really
"private", he must document it or know how it works.

How does that make it not private. Private has never meant "accessible
to noone". And sure he must document it and know how it works. But that
documentation can remain private, limited to the developers of the
product. It doesn't have to be publicly documented.

If the audience is the programmer(s) who implement the "private" API it
is not private but public. Even the "public" API is somewhat "private" to
a user of a program that uses that API. The public is not virtually
anyone here. Depends at which level you look in the system.
I think there is a general consensus about on what level to look when we
are talking about private and public attributes. You can of course
start talking at a whole different level and as such use these words
with a meaning different than normally understood. But that will just
make it harder for you to get your ideas accross.

--
Antoon Pardon
Jun 27 '08 #104
Antoon Pardon a écrit :
On 2008-06-04, NickC <nc******@gmail.comwrote:
>On Jun 4, 4:09 am, "Russ P." <Russ.Paie...@gmail.comwrote:
>>What is it about leading underscores that bothers me? To me, they are
like a small pebble in your shoe while you are on a hike. Yes, you can
live with it, and it does no harm, but you still want to get rid of it.
With leading underscores, you can see *at the point of dereference*
that the code is accessing private data.
@NickC : InMyArms(tm) !
But the leading underscore doesn't tell you whether it is your own
private date, which you can use a you see fit, or those of someone
else, which you have to be very carefull with.
That's why we have __name_mangling too. Consider '_' as 'protected' and
'__' as private.
Jun 27 '08 #105
Russ P. a écrit :
>(snip)
(answering to Carl Bank) I thought you were saying that encapsulation or so-called "data
hiding" is worthless.
As far as I'm concerned, I view encapsulation as very desirable, and
data-hidding as totally worthless when applied to Python's object model.
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.
Given your very recent discovery of what 'dynamic' *really* means in
Python (like, for exemple, dynamically adding / replacing attributes -
including methods - on a per-class or per-instance basis), possibly, yes.
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.
Why so ?
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).
Why so ?

Metaprogramming (including monkeypatching) is part of the pythoneer's
toolbox, and while it's not something to use without pretty good
reasons, it has many times proven to be a real life saver. In languages
not allowing it, the solutions to the class of problems easily solved by
monkeypatching happens to be at best a kludge, at worst plain
unsolvable, at least without too much effort to be even worth it. Your
above proposition would arbitrarily make possible and useful things
either uselessly complicated or near impossible.
Jun 27 '08 #106
On Jun 3, 6:54 pm, sturlamolden <sturlamol...@yahoo.nowrote:
On May 24, 3:41 pm, Sh4wn <luckyluk...@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 has no data hiding because C++ has (void *).

Python underscores does some name mangling, but does not attempt any
data hiding.

Python and C has about the same approach to data hiding. It is well
tried, and works equally well in both languages:

# this is mine, keep your filthy paws off!!!

Irresponsible programmers should not be allowed near a computer
anyway. If you use data hiding to protect your code from yourself,
what you really need is some time off to reconsider your career.
So, you are stating that no API programmer using Python *ever* has a
valid or genuine reason for wanting (even if he can't have it) genuine
'hiding' of internal state or members from consumers of his (or
her...) API?

Michael Foord
http://www.ironpythoninaction.com/
Jun 27 '08 #107
On Jun 5, 3:26 pm, Fuzzyman <fuzzy...@gmail.comwrote:
So, you are stating that no API programmer using Python *ever* has a
valid or genuine reason for wanting (even if he can't have it) genuine
'hiding' of internal state or members from consumers of his (or
her...) API?

Michael Foordhttp://www.ironpythoninaction.com/
If you are an API programmer, the __all__ attribute of a package or
module provides all the internal data hiding you need.
Jun 27 '08 #108
On Jun 5, 4:47 am, Bruno Desthuilliers <bruno.
42.desthuilli...@websiteburo.invalidwrote:
Antoon Pardon a écrit :
On 2008-06-04, NickC <ncogh...@gmail.comwrote:
On Jun 4, 4:09 am, "Russ P." <Russ.Paie...@gmail.comwrote:
What is it about leading underscores that bothers me? To me, they are
like a small pebble in your shoe while you are on a hike. Yes, you can
live with it, and it does no harm, but you still want to get rid of it..
With leading underscores, you can see *at the point of dereference*
that the code is accessing private data.

@NickC : InMyArms(tm) !
But the leading underscore doesn't tell you whether it is your own
private date, which you can use a you see fit, or those of someone
else, which you have to be very carefull with.

That's why we have __name_mangling too. Consider '_' as 'protected' and
'__' as private.
Only in some vague, fuzzy sense.

My understanding is that the single underscore in a class definition
is a convention only and has no actual effect whatsoever. In C++ (and
Java?), on the other hand, the "protected" keyword *really* prevents
the client from accessing the data or method, but it allows access to
derived classes. The "private" keyword goes further and prevents
access even by derived classes. The double leading underscore in
Python does no such thing.

By the way, people often claim that "friend" classes in C++ violate
encapsulation. That is a common misunderstanding. They do not violate
encapsulation because a class must declare its own "friends." In other
words, the determination of who gets acces to the private data in a
class is determined within the class itself. Declaring another class a
friend gives it access to your data but does not give you access to
its data. (At least that's my recollection, though I haven't used C++
for several years.)
Jun 27 '08 #109
On Jun 5, 2:07 pm, "Russ P." <Russ.Paie...@gmail.comwrote:
The "private" keyword goes further and prevents
access even by derived classes. The double leading underscore in
Python does no such thing.
Who develops these derived classes ? A competitor ? A malicious
hacker ? A spammer ? Who are you trying to hide your precious classes
from that the double leading underscore is not good enough
protection ? Even with a 'private' keyword, what stops them from doing
s/private/public/g ? Seriously, the "underscores are ugly" argument
has some merit but language enforced data hiding is overrated, if not
downright silly.
Jun 27 '08 #110
On Jun 5, 4:53 am, Bruno Desthuilliers <bruno.
42.desthuilli...@websiteburo.invalidwrote:
Russ P. a écrit :
Given your very recent discovery of what 'dynamic' *really* means in
Python (like, for exemple, dynamically adding / replacing attributes -
including methods - on a per-class or per-instance basis), possibly, yes.
My "very recent" discovery? Funny, I thought I knew that several years
ago. You must know more about me than I know about myself.
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.

Why so ?
Why should the client of a class not be able to declare a *private*
member of the class? You're kidding, right? Do you mind if I tell you
how to arrange the furniture in your bedroom?
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).

Why so ?

Metaprogramming (including monkeypatching) is part of the pythoneer's
toolbox, and while it's not something to use without pretty good
reasons, it has many times proven to be a real life saver. In languages
not allowing it, the solutions to the class of problems easily solved by
monkeypatching happens to be at best a kludge, at worst plain
unsolvable, at least without too much effort to be even worth it. Your
above proposition would arbitrarily make possible and useful things
either uselessly complicated or near impossible.
For the record, I have made it abundantly clear that I don't think
Python should not have as rigorous an encapsulation regime as C++ or
Java. The worst that could happen with my proposition is that you
would need to use a "mangled" name to access private data or methods.
But you will be using the name many times, you can reassign your own
name, of course, so the mangled name need not appear more than once
where it is needed.
Jun 27 '08 #111
On Jun 5, 11:25 am, George Sakkis <george.sak...@gmail.comwrote:
On Jun 5, 2:07 pm, "Russ P." <Russ.Paie...@gmail.comwrote:
The "private" keyword goes further and prevents
access even by derived classes. The double leading underscore in
Python does no such thing.

Who develops these derived classes ? A competitor ? A malicious
hacker ? A spammer ? Who are you trying to hide your precious classes
from that the double leading underscore is not good enough
protection ? Even with a 'private' keyword, what stops them from doing
s/private/public/g ? Seriously, the "underscores are ugly" argument
has some merit but language enforced data hiding is overrated, if not
downright silly.
I did not claim that Python should have the same encapsulation rules
as C++. I was merely comparing the two in reply to a post that claimed
a similarity.
Jun 27 '08 #112
For the record, I have made it abundantly clear that I don't think
Python should not have as rigorous an encapsulation regime as C++ or
Java. The worst that could happen with my proposition is that you
would need to use a "mangled" name to access private data or methods.
But you will be using the name many times, you can reassign your own
name, of course, so the mangled name need not appear more than once
where it is needed.
Let me try that again:

For the record, I have made it abundantly clear that I don't think
Python should have as rigorous an encapsulation regime as C++ or
Java. The worst that could happen with my proposition is that you
would need to use a "mangled" name to access private data or methods.
But if you will be using the name many times, you can reassign your
own
name, of course, so the mangled name need not appear more than once
where it is needed.
Jun 27 '08 #113
In article
<ec**********************************@c19g2000prf. googlegroups.com>,
"Russ P." <Ru**********@gmail.comwrote:
In C++ (and
Java?), on the other hand, the "protected" keyword *really* prevents
the client from accessing the data or method, but it allows access to
derived classes. The "private" keyword goes further and prevents
access even by derived classes.
In C++, it does no such thing. Consider this class declaration in
MySecretClass.h:

class MySecretClass {
private:
int foo;
};

All somebody has to do to get at the private data is:

#define private public
# include <MySecretClass.h>
#undef private

If playing preprocessor games isn't your thing, there's a whole multitude
of other tricks you can play with pointers and typecasts that will get you
access to foo in other ways.

But, you protest, you're not supposed to do that! Well, of course not.
But you're not supposed to ignore the leading underscore convention in
Python either. That's the nice thing about freedom of religion; you get to
pick which particular sins you want to get freaked out about.

I'm pretty weak on Java, but my understanding is that it's in better shape
here, since it has neither textual inclusion of header files, nor pointers.
You might have to resort to JNI :-)
Jun 27 '08 #114
On Jun 5, 12:20 pm, Roy Smith <r...@panix.comwrote:
All somebody has to do to get at the private data is:

#define private public
# include <MySecretClass.h>
#undef private
Well, that shows the weakness of the C/C++ header files. The "include"
directive merely does a simple text substitution, which is pretty lame
as far as I am concerned. As you say, Java has moved beyond that, and
Ada has always been more sophisticated than that.

By the way, my recollection is that in C++ access defaults to private
if nothing is declared explicity. So normally the "private"
declaration is unnecessary. If it is left out, your little trick won't
work. But your point is still valid.
Jun 27 '08 #115
Russ P. wrote:
On Jun 2, 5:11 pm, Paul Rubin <http://phr...@NOSPAM.invalidwrote:
>"Russ P." <Russ.Paie...@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.

It did seem a bit odd to me when I realized that you can add data
members (or even a "methods") to a class from completely outside the
class definition. That can be risky, of course, and as you suggest,
perhaps it shouldn't even be allowed by default.

I usually find that it's safer to initialize in the constructor all
(or nearly all) of the data members that will be needed in a class. If
I need a list that will be populated later, for example, I reserve the
name with an empty list in the constructor. Then, if for some reason
the list gets accessed before it is populated, I don't get an
exception.
That is EXACTLY when I want an exception, I did something that shouldn't happen.
You also are missing the nice ability of python to use hasattr() to find out
if a class instance has a method/attribute. I use hasattr() to test for
presence or absence of methods/attributes quite a lot. In the past I did what
you describe, but found that to be limiting and a throwback to when I used
languages that could not do introspection. I can test to see if the attribute
exists, if it is empty, which can be two very different conditions that require
two different actions. The only way you can do that is to initialize it to
None. While this works it is a fictitious construct that we all learned when we
were writing Fortran, Basic or Cobol years ago (oops I think I just revealed
that I'm an 'old timer'). Now I just do: if hasattr(self, 'listInQuestion') and
I can tell if it has been created (either by constructor) or by some other
method. This works particularly well when I do caching of data in objects that
are shared among methods. I can also do hasattr(object, 'methodInQuestion') to
see if the object implements an interface that I require.

May be a little off topic, but I think it is relevant.

-Larry
Jun 27 '08 #116
On Wed, Jun 4, 2008 at 2:54 PM, Roy Smith <ro*@panix.comwrote:
In article <87************@benfinney.id.au>,
Ben Finney <bi****************@benfinney.id.auwrote:
>By definition, "private" functions are not part of the publicly
documented behaviour of the unit. Any behaviour exhibited by some
private component is seen externally as a behaviour of some public
component.

You know the difference between theory and reality? In theory, there is
none... Sometimes it's useful to test internal components. Imagine this
class:

class ArmegeddonMachine:
def pushTheButton(self):
"Destroy a random city"
city = self._pickCity()
self._destroy(city)

def _pickCity():
cities = ['New York', 'Moscow', 'Tokyo', 'Beijing', 'Mumbai']
thePoorSchmucks = random.choice(cities)
return 'New York'

def _destroy(self, city):
missle = ICBM()
missle.aim(city)
missle.launch()

The only externally visible interface is pushTheButton(), yet you don't
really want to call that during testing. What you do want to do is test
that a random city really does get picked.

You can do one of two things at this point. You can say, "But, that's not
part of the externally visible interface" and refuse to test it, or you can
figure out a way to test it. Up to you.
--
http://mail.python.org/mailman/listinfo/python-list
Sorry for the long post in advance. I'm busy studying unit testing$B!"(Band
here is how I would go about testing the above code.

1) Make the code more testable through public (not private)
interfaces. ie, split out the functionality into more public, but
still properly encapsulated forms (modules/classes, etc). Don't need
to make everything public, just enough that it's testable without
digging into privates attributes, but still well-encapsulated.

2) Link the split-up logic together (eg, in class constructors). Use
public attributes for this. Or use private attributes, but make them
updatable through public methods.

3) In the unit tests update the object being tested, so it uses mock
objects instead of the ones it uses by default (aka dependency
injection).

4) Run the methods to be tested, and check that the mock objects were
updated correctly.

Here is an example (very rough, untested & incomplete):

# Updated armageddonmachine module:

class CityPicker:
def pick(self):
cities = ['New York', 'Moscow', 'Tokyo', 'Beijing', 'Mumbai']
thePoorSchmucks = random.choice(cities)
return 'New York' # Your bug is still here

class Destroyer:
def destroy(self, city):
missle = ICBM()
missle.aim(city)
missle.launch()

class ArmegeddonMachine:
def __init__(self):
self.city_picker = CityPicker()
self.destroyer = Destroyer()

def pushTheButton(self):
"Destroy a random city"
city = self.city_picker.pick()
self.destroyer.destroy(city)

# unit test module for armageddonmachine
# Only has tests for CityPicker and ArmageddonMachine

import armageddonmachine

# Unit test code for CityPicker
# -- Mock objects --
class MockRandom:
def __init__(self):
self.choose = None
def choice(self, list_):
assert self.choose is not None
return list_[self.choose]
class TestCityPicker:
def setup()
# Setup code run before each unit test in this class
self.city_picker = CityPicker()
self._bkp_random = armaggedonmachine.random

def teardown()
# Teardown code run after each unit test in this class
armaggedonmachine.random = self._bkp_random

def test_should_pick_random_cities_correctly(self):
armaggedonmachine.random = MockRandom()

armaggedonmachine.choose = 0
assert city_picker.pick() == 'New York'

armaggedonmachine.choose = 1
assert city_picker.pick() == 'Moscow' # This will catch your bug

armaggedonmachine.choose = 2
assert city_picker.pick() == 'Tokyo'

armaggedonmachine.choose = 3
assert city_picker.pick() == 'Beijing'

armaggedonmachine.choose = 4
assert city_picker.pick() == 'Mumbai'

# Unit test code for ArmageddonMachine

# -- Mock Classes --
class MockCityPicker:
def __init__(self):
self.city_to_pick = "Test City"

def pick(self):
return self.city_to_pick
class MockDestroyer:
def __init__(self):
self.destroyed_cities = set()

def destroy(self, city):
self.destroyed_cities.append(city)
# -- Unit Tests

class TestArmageddonMachine:

def setup(self):
# Setup code that runs before each unit test in this class
self.machine = ArmageddonMachine()
self._bkp_picker = self.machine.city_picker
self._bkp_destroyer = self.machine.destroyer
self.machine.city_picker = MockCityPicker()
self.machine.destroyer = MockCityDestroyer()

def test_should_destroy_a_city(self):
self.machine.pushTheButton()
assert self.machine.destroyer.destroyed_cities == "Test City"
Jun 27 '08 #117
"Russ P." <Ru**********@gmail.comwrites:
By the way, my recollection is that in C++ access defaults to private
if nothing is declared explicity. So normally the "private"
declaration is unnecessary. If it is left out, your little trick won't
work.
How about #define class struct
Jun 27 '08 #118
Roy Smith <ro*@panix.comwrites:
In article <87************@benfinney.id.au>,
Ben Finney <bi****************@benfinney.id.auwrote:
Then what you're really testing is the interactions of the "push
the button" function with its external interface: you're asserting
that the "push the red button" function actually uses the result
from "pick a random city" as its target.

No, that's not what I'm testing at all. I want to test that the
cities really do get picked randomly.
Then you need to make a design decision, by *specifying* that expected
behaviour in some public API.

Either "pick a random city" is public API with the expected behaviour
that it will return a random city from a publicly-specified list of
cities; or the "push the button" function has some
externally-verifiable target that is specified.

If the behaviour you describe isn't part of the specified API, then it
*doesn't matter* how the city gets picked (i.e. it's an internal
implementation detail); selecting New York every time doesn't go
against any description of the behaviour of the application, so it's
not a bug, but an internal implementation detail that doesn't deserve
to be unit tested.

If you want "always chooses the same city" to be a bug, then you are
specifying some externally-expected behaviour of the application code,
and that expectation needs to be specified in such a way that you can
make an automated assertion about it in a unit test.

Once you've decided which public API is specified as providing that
behaviour, that's the point at which the unit test should be asserting
that behaviour.

--
\ "Know what I hate most? Rhetorical questions." -- Henry N. Camp |
`\ |
_o__) |
Ben Finney
Jun 27 '08 #119
On Jun 5, 2:27 pm, Dennis Lee Bieber <wlfr...@ix.netcom.comwrote:
On Thu, 5 Jun 2008 11:36:28 -0700 (PDT), "Russ P."
<Russ.Paie...@gmail.comdeclaimed the following in comp.lang.python:
would need to use a "mangled" name to access private data or methods.
But you will be using the name many times, you can reassign your own
name, of course, so the mangled name need not appear more than once
where it is needed.

Which will break the first time the "innards" rebind a value to the
mangled name, as the "simplified" external name will still be bound to
the previous value.
I'm not sure you understood what I meant. In current Python, if I need
access to data element __XX in class YourClass, I can use
ZZ._YourClass__XX, but if I don't want to clutter my code with that
mangled name, I can just write

XX = ZZ._YourClass__XX

and refer to it from that point on as XX. Obviously if the meaning of
__XX changes within class ZZ, this will break, but that's why you are
supposed to avoid using private data in the first place.
Jun 27 '08 #120
On Jun 5, 2:57 pm, Hrvoje Niksic <hnik...@xemacs.orgwrote:
"Russ P." <Russ.Paie...@gmail.comwrites:
By the way, my recollection is that in C++ access defaults to private
if nothing is declared explicity. So normally the "private"
declaration is unnecessary. If it is left out, your little trick won't
work.

How about #define class struct
I never thought of that one. I wonder what the C++ gurus would say
about that.

Let me guess. They'd probably say that the access restrictions are for
your own good, and bypassing them is bound to do you more harm than
good in the long run. And they'd probably be right. Just because you
can break into a box labeled "DANGER HIGH VOLTAGE," that doesn't make
it a good idea.

This just goes to show that the whole idea of using header files as
simple text insertions is flaky to start with, and adding the
preprocessor just compounds the flakiness. Needless to say, I'm not a
big fan of C and C++.
Jun 27 '08 #121
Someone asked about Java;

class FieldTest {
public String publicString = "Foobar";
private String privateString = "Hello, World!";
}

import java.lang.reflect.Field;

public class Test4 {
public static void main(String args[]) {
final Field fields[] =
FieldTest.class.getDeclaredFields();
for (int i = 0; i < fields.length; ++i) {
System.out.println("Field: " + fields[i]);
}
}
}

OUTPUT >>>>
Field: public java.lang.String FieldTest.publicString
Field: private java.lang.String FieldTest.privateString

And to edit it;

import java.lang.reflect.Field;

public class Test7 {
public static void main(String args[])
throws Exception {
final Field fields[] =
FieldTest.class.getDeclaredFields();
for (int i = 0; i < fields.length; ++i) {
if ("privateString".equals(fields[i].getName())) {
FieldTest fieldTest = new FieldTest();
Field f = fields[i];
f.setAccessible(true);
System.out.println(f.get(fieldTest));
f.set(fieldTest, "Modified Field");
System.out.println(f.get(fieldTest));
break;
}
}
}
}

OUTPUT >>>>
Hello, World!
Modified Field

Enjoy.
Jun 27 '08 #122
Russ P. a écrit :
On Jun 4, 4:29 am, NickC <ncogh...@gmail.comwrote:
>On Jun 4, 4:09 am, "Russ P." <Russ.Paie...@gmail.comwrote:
>>What is it about leading underscores that bothers me? To me, they are
like a small pebble in your shoe while you are on a hike. Yes, you can
live with it, and it does no harm, but you still want to get rid of it.
With leading underscores, you can see *at the point of dereference*
that the code is accessing private data. With a "this is private"
keyword you have no idea whether you're accessing private or public
data, because the two namespaces get conflated together.

That is true. But with the "priv" keyword you'll discover quickly
enough that you are trying to access private data (as soon as you run
the program).
With the current convention, you don't even have to run the program - as
soon as you *type* the name, you know you're accessing implementation stuff.
And even if a "priv" keyword is added, you are still
free to use the leading underscore convention if you wish.
What does this "priv keyword" buy you then ? Seriously ?
The idea of being able to discern properties of an object by its name
alone is something that is not normally done in programming in
general.
Want to talk about the hungarian notation that is everywhere in MS
Windows code ?-) or about the so common C++ coding guideline that
insists on prefixing "data members" with a m_ or a w_ ?-)

More seriously: yes, you usually try to convey something about some
relevant properties of the object in the identifier. Like, you know,
using plurals for collections. Or i, j as loop indices.
Yes, of course you should choose identifiers to be
descriptive of what they represent in the real world, but you don't
use names like "intCount," "floatWeight," or "MyClassMyObject" would
you?
Nope.
Why not?
Because the naming convention for variables is all_lower_with_underscores.

Also, because 'count' is likely enough to be an integer and 'weight'
likely enough to be a float - and else another numeric. While 'counts'
and 'weights' are likely enough to be collections (likely lists) of
resp. integers and floats.
Jun 27 '08 #123
Russ P. a écrit :
On Jun 5, 4:53 am, Bruno Desthuilliers <bruno.
42.desthuilli...@websiteburo.invalidwrote:
>Russ P. a écrit :
>Given your very recent discovery of what 'dynamic' *really* means in
Python (like, for exemple, dynamically adding / replacing attributes -
including methods - on a per-class or per-instance basis), possibly, yes.

My "very recent" discovery? Funny, I thought I knew that several years
ago.
Looks like I mistook your
"""
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
"""

as "I just realized (...)"

Sorry for having read too fast.
>>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.
Why so ?

Why should the client of a class not be able to declare a *private*
member of the class? You're kidding, right?
I'm dead serious. I often add implementation attributes to either a
class or an instance. These *are* implementation parts, not API.
Do you mind if I tell you
how to arrange the furniture in your bedroom?
I must be a bit dumb, but I don't see how human interaction problems
relate to enforced access restriction in an OO programming language.
>>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).
Why so ?

Metaprogramming (including monkeypatching) is part of the pythoneer's
toolbox, and while it's not something to use without pretty good
reasons, it has many times proven to be a real life saver. In languages
not allowing it, the solutions to the class of problems easily solved by
monkeypatching happens to be at best a kludge, at worst plain
unsolvable, at least without too much effort to be even worth it. Your
above proposition would arbitrarily make possible and useful things
either uselessly complicated or near impossible.

For the record, I have made it abundantly clear that I don't think
Python should not have as rigorous an encapsulation regime as C++ or
Java. The worst that could happen with my proposition is that you
would need to use a "mangled" name to access private data or methods.
That's already the case - when you use __name_mangling. And if there's
no effective access restriction, then what the point of having this
'priv' keyword ?
But you will be using the name many times, you can reassign your own
name, of course, so the mangled name need not appear more than once
where it is needed.
Once again, I just don't see the point. Either you want effective access
restriction in Python, or you don't. And if you don't, what would this
'priv' keyword be useful to ?
Jun 27 '08 #124
Russ P. a écrit :
On Jun 5, 2:27 pm, Dennis Lee Bieber <wlfr...@ix.netcom.comwrote:
>On Thu, 5 Jun 2008 11:36:28 -0700 (PDT), "Russ P."
<Russ.Paie...@gmail.comdeclaimed the following in comp.lang.python:
>>would need to use a "mangled" name to access private data or methods.
But you will be using the name many times, you can reassign your own
name, of course, so the mangled name need not appear more than once
where it is needed.
Which will break the first time the "innards" rebind a value to the
mangled name, as the "simplified" external name will still be bound to
the previous value.

I'm not sure you understood what I meant. In current Python, if I need
access to data element __XX in class YourClass, I can use
ZZ._YourClass__XX, but if I don't want to clutter my code with that
mangled name, I can just write

XX = ZZ._YourClass__XX

and refer to it from that point on as XX.

Obviously if the meaning of
__XX changes within class ZZ, this will break, but that's why you are
supposed to avoid using private data in the first place.
AFAICT, What Dennis meant is that the binding of ZZ._YourClass__XX
changes between the moment you bind it to local XX and the moment you
use it, then you're out.
Jun 27 '08 #125
On Jun 6, 8:25 am, Bruno Desthuilliers <bruno.
42.desthuilli...@websiteburo.invalidwrote:
>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.
Why so ?
Why should the client of a class not be able to declare a *private*
member of the class? You're kidding, right?

I'm dead serious. I often add implementation attributes to either a
class or an instance. These *are* implementation parts, not API.
If a client accesses a data member of a class, then by definition that
member is not really private, so letting the client create a new data
member and declare it as private seems a bit silly to me. Actually,
just letting the client create the new data member, private or not,
seems like a bit of a stretch to me, but I'll leave that be.
For the record, I have made it abundantly clear that I don't think
Python should not have as rigorous an encapsulation regime as C++ or
Java. The worst that could happen with my proposition is that you
would need to use a "mangled" name to access private data or methods.

That's already the case - when you use __name_mangling. And if there's
no effective access restriction, then what the point of having this
'priv' keyword ?
But you will be using the name many times, you can reassign your own
name, of course, so the mangled name need not appear more than once
where it is needed.

Once again, I just don't see the point. Either you want effective access
restriction in Python, or you don't. And if you don't, what would this
'priv' keyword be useful to ?
In the end, I suppose it boils down to aesthetics and personal
preference.

The leading-underscore convention bothers me for two reasons: (1) like
the OP, I don't like the way it makes my code look, and (2) it is a
signal to a person reading the code, but it has no actual effect in
the interpreter.

I think the concept of private data and methods is important enough to
be implemented with more than just a tacky naming convention. That is
why I suggested the "priv" keyword. At the same time, I realize that
people will occasionally be frustrated if they are rigorously denied
access to all private data, which is why I suggested an "indirect"
method of access through mangled names.

You can argue that such indirect access defeats the whole idea of
private data, but at least it alerts the client to the fact that he
(or she or it) is accessing private data -- and it does so without
using Hungarian notation.

I would let the "priv" keyword also be used for data or functions at
file scope. It just seems logical to me. Again, some name mangling
convention could be concocted for those who think they really need
access.

Actually, the whole objection to denied access baffles me a bit. Does
anyone object to not having access from outside a function to local
variables within the function? I doubt it. The other thing is that the
vast majority of Python software, I would guess, is provided with
source code. How many Python applications or libraries are provided
without source code? If you have the source code, you can obviously
just delete the "priv" keyword anywhere or everywhere it appears. And
if you have a major client who insists on access to all the internals,
just delete all occurrences of "priv" before you ship the code (or
don't use it to start with).

Jun 27 '08 #126
On Jun 6, 8:28 am, Bruno Desthuilliers <bruno.
42.desthuilli...@websiteburo.invalidwrote:
Russ P. a écrit :
On Jun 5, 2:27 pm, Dennis Lee Bieber <wlfr...@ix.netcom.comwrote:
On Thu, 5 Jun 2008 11:36:28 -0700 (PDT), "Russ P."
<Russ.Paie...@gmail.comdeclaimed the following in comp.lang.python:
>would need to use a "mangled" name to access private data or methods.
But you will be using the name many times, you can reassign your own
name, of course, so the mangled name need not appear more than once
where it is needed.
Which will break the first time the "innards" rebind a value tothe
mangled name, as the "simplified" external name will still be bound to
the previous value.
I'm not sure you understood what I meant. In current Python, if I need
access to data element __XX in class YourClass, I can use
ZZ._YourClass__XX, but if I don't want to clutter my code with that
mangled name, I can just write
XX = ZZ._YourClass__XX
and refer to it from that point on as XX.
Obviously if the meaning of
__XX changes within class ZZ, this will break, but that's why you are
supposed to avoid using private data in the first place.

AFAICT, What Dennis meant is that the binding of ZZ._YourClass__XX
changes between the moment you bind it to local XX and the moment you
use it, then you're out.
Perhaps I should have stipulated that this should be done only in a
local scope and in an application that is not multi-threaded. Then I
don't see how you can have a problem.
Jun 27 '08 #127
On Wed, Jun 4, 2008 at 2:02 PM, Antoon Pardon <ap*****@forel.vub.ac.bewrote:
Now of course noone would defend such a limitation on the grounds
that one doesn't need the general case and that the general case
will only save you some vertical space.

But when it came to the ternary operator that was exactly the
argument used, to defend the lack of it.
As far as I remember, the primary motivation was developers experience
with the ternary operator in other languages, especially C, where it
was found to hurt readability. At least in my experience, it is much
much more common to see the ternary operator making code more
obfuscated than easing readability. Time will tell if Python's if-else
expression will be abused in the same way.
--
mvh Björn
Jun 27 '08 #128
BJörn Lindqvist wrote:
On Wed, Jun 4, 2008 at 2:02 PM, Antoon Pardon <ap*****@forel.vub.ac.bewrote:
>Now of course noone would defend such a limitation on the grounds
that one doesn't need the general case and that the general case
will only save you some vertical space.

But when it came to the ternary operator that was exactly the
argument used, to defend the lack of it.

As far as I remember, the primary motivation was developers experience
with the ternary operator in other languages, especially C, where it
was found to hurt readability. At least in my experience, it is much
much more common to see the ternary operator making code more
obfuscated than easing readability. Time will tell if Python's if-else
expression will be abused in the same way.
Expression IF statements are most useful in situations where you can't
have multiple statements. In C, that was usually in macros, or occasionally
in a function call:

printf("Boolean value: %s\n", b ? "True" : "False");

was useful, for example. The syntax was probably a bad choice.
The classic expression IF (an ALGOL extension) was

x := IF b THEN 1 ELSE 0;

Surrounded with parentheses, that form could be used in any expression
context.

Given Python's approach to indentation, conditionals
within expressions (and iteration; one could have FOR / YIELD) don't
fit the syntax. That's why lambda expressions in Python are so limited.
Python already has local functions; you can write:

def foo(n) :
def bar(m) :
print "In BAR",n, m
bar(n+1)

which also allows you to do anything you can do with a lambda expression.
You can have control structure, and it reads like ordinary Python.
So there's no real need for an expression IF operator.

John Nagle

Jun 27 '08 #129
Paul Rubin <httpwrote:
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.
No it wouldn't. Think about multiple inheritance.

-- [mdw]
Jun 27 '08 #130
Hrvoje Niksic <hn*****@xemacs.orgwrote:
How about #define class struct
Won't work. Consider `template<class T...'.

-- [mdw]
Jun 27 '08 #131
Russ P. <Ru**********@gmail.comwrote:
The idea of being able to discern properties of an object by its name
alone is something that is not normally done in programming in
general.
Really? You obviously haven't noticed Prolog, Smalltalk, Haskell, ML,
or Erlang then. And that's just the ones I can think of off the top of
my head.

* Prolog and Erlang distinguish atoms from variables by the case of
the first letter; also `_' is magical and is equivalent to a new
variable name every time you use it.

* Smalltalk distinguishes between global and local variables according
to the case of the first letter.

* Haskell distinguishes between normal functions and constructors
(both data constructors and type constructors) by the case of the
first letter, and has Prolog's `_' convention.

* ML allows a single-quote in variable names, but reserves names
beginning with a single-quote for type variables. It also has
Prolog's `_' convention.

As far as I can see, discerning properties of a thing from its name
seems relatively common.

-- [mdw]
Jun 27 '08 #132
Fuzzyman <fu******@gmail.comwrote:
So, you are stating that no API programmer using Python *ever* has a
valid or genuine reason for wanting (even if he can't have it) genuine
'hiding' of internal state or members from consumers of his (or
her...) API?
I don't want to speak for whoever you were responding to, but from my
point of view...

Yes.

I understand the difference between the documented interface of a system
and the details of its implementation. But sometimes it can be useful
to take advantage of implementation details, particularly if the
published interface is inadequate in some way. Whether or not I choose
to make use of implementation details is a trade-off between immediate
convenience and maintainability, but that's something I can make a
rational decision about.

By enforcing your `data hiding', you're effectively telling me that I'm
too stupid to make rational decisions of this sort. And that's actually
extremely insulting.

-- [mdw]
Jun 27 '08 #133
In article <sl****************@metalzone.distorted.org.uk>,
Mark Wooding <md*@distorted.org.ukwrote:
* Prolog and Erlang distinguish atoms from variables by the case of
the first letter; also `_' is magical and is equivalent to a new
variable name every time you use it.
Can you explain that in more detail? A literal reading of what you wrote
would mean that if you did (assuming this is even legal syntax):

_ = 1;
y = _;

the _'s are different variables, which is absurd enough to make me believe
I just misunderstood you.
Jun 27 '08 #134
In article <sl****************@metalzone.distorted.org.uk>,
Mark Wooding <md*@distorted.org.ukwrote:
By enforcing your `data hiding', you're effectively telling me that I'm
too stupid to make rational decisions of this sort. And that's actually
extremely insulting.
I think that's taking it a bit far. Python doesn't let you manipulate
pointers directly. For example, I can't do:

s = "foo"
sp = address(s)
sp[2] = 'x'
print s

and have it print "fox". Is this because I'm too stupid to make rational
decision of this sort? No, it's because the Python programming model
exposes some things and hides others which are deemed inappropriate or too
low level. One of the things it hides is direct access to raw memory. I
don't see that as fundamentally different from a C++ string class which
declares its internal buffer to be private. If the goose's pot is black,
then the gander's kettle is an equal shade of dark grey.
Jun 27 '08 #135

I don't know about Erlang (though I'd think it's behaviour sould be similar to
prolog), but at least in Prolog, yes, _ and _ are different variables. The whole
idea of "_" is that it is a placeholder that can bind to anything, but will be
immediately discarded. It's just syntactic sugar so you don't have to create new
names for things you don't care about, which could be a problem in prolog(once
bound, cannot be bound again on the same branch) or erlang (once bound, bound
forever).

I just tried on erlang:

f(0,_) -1+_;
f(X,_) -X*f(X-1,_).

produces an error:

../t.erl:4: variable '_' is unbound
../t.erl:5: variable '_' is unbound

(referring to the right side uses of the _ symbol)

while the definition:

f(0,Y)->1+Y;
f(X,Y)->X*f(X-1,Y).

produces a [very weird, just for testing purposes, don't use it at home] version
of 'factorial'.

So, you understood well.

As I haven't been following this thread, I won't go offtopic talking about
functional languages. But yes, on functional (and declarative?) languages, it
makes a lot of sense to have a 'symbol' that represents a new variable any time
you use it.

Cheers,

--
Luis Zarrabeitia
Facultad de Matemática y Computación, UH
http://profesores.matcom.uh.cu/~kyrie
Quoting Roy Smith <ro*@panix.com>:
In article <sl****************@metalzone.distorted.org.uk>,
Mark Wooding <md*@distorted.org.ukwrote:
* Prolog and Erlang distinguish atoms from variables by the case of
the first letter; also `_' is magical and is equivalent to a new
variable name every time you use it.
Can you explain that in more detail? A literal reading of what you wrote
would mean that if you did (assuming this is even legal syntax):

_ = 1;
y = _;

the _'s are different variables, which is absurd enough to make me believe
I just misunderstood you.
--
http://mail.python.org/mailman/listinfo/python-list
Jun 27 '08 #136
On Jun 8, 5:52 am, Mark Wooding <m...@distorted.org.ukwrote:
By enforcing your `data hiding', you're effectively telling me that I'm
too stupid to make rational decisions of this sort. And that's actually
extremely insulting.
1) I suggest you not take it personally.

2) Local data within functions is hidden. Should you have access to
that too? Are you insulted that you don't?

3) I have suggested that "indirect" or "back door" access could be
provided to private data and methods via some sort of name mangling
rule akin to the current rule for leading double underscores. This
would provide access in a pinch, but it would make sure the client is
aware that he or she or it is accessing private data (and it would do
so without leading underscores).

4) My understanding is that most Python software is released or
shipped as source code (or at least with the source code included).
That means that the client would need only to remove my suggested
"priv" keyword to gain access. Have you ever actually had to use
Python software for which you had no access to the source code?
Jun 27 '08 #137
On Jun 8, 5:40 am, Mark Wooding <m...@distorted.org.ukwrote:
Russ P. <Russ.Paie...@gmail.comwrote:
The idea of being able to discern properties of an object by its name
alone is something that is not normally done in programming in
general.

Really? You obviously haven't noticed Prolog, Smalltalk, Haskell, ML,
or Erlang then. And that's just the ones I can think of off the top of
my head.

* Prolog and Erlang distinguish atoms from variables by the case of
the first letter; also `_' is magical and is equivalent to a new
variable name every time you use it.

* Smalltalk distinguishes between global and local variables according
to the case of the first letter.

* Haskell distinguishes between normal functions and constructors
(both data constructors and type constructors) by the case of the
first letter, and has Prolog's `_' convention.

* ML allows a single-quote in variable names, but reserves names
beginning with a single-quote for type variables. It also has
Prolog's `_' convention.

As far as I can see, discerning properties of a thing from its name
seems relatively common.
Well, "common" in Prolog, Smalltalk, Haskell, ML, and Erlang is hardly
common in general. I'll bet that Java and C/C++ are used more in North
Dakota than all those languages combined are used in the entire world.
That's not to say they aren't interesting academic languages, of
course.

As for using the case of the first letter to distinguish between local
and global variables, is that just a naming convention or is it
actually enforced by the compiler (or interpreter)? If it's actually
enforced, that seems rather restrictive to me. What if I want to name
a local variable after a proper name or an uppercase acronym? I guess
I'm just out of luck.
Jun 27 '08 #138
Sh4wn wrote:
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.
Others touched on this, but I thought I'd throw it in here as well since
I was just reading about this. Apparently the double underscore
convention has nothing to do with data hiding. It's simply a mechanism
for avoiding name clashes, and data hiding only *seems* to be a result
of it.

Not that that helps your situation any. :)
Jun 27 '08 #139
Mark Wooding a écrit :
Russ P. <Ru**********@gmail.comwrote:
>The idea of being able to discern properties of an object by its name
alone is something that is not normally done in programming in
general.

Really? You obviously haven't noticed Prolog, Smalltalk, Haskell, ML,
or Erlang then. And that's just the ones I can think of off the top of
my head.

* Prolog and Erlang distinguish atoms from variables by the case of
the first letter; also `_' is magical and is equivalent to a new
variable name every time you use it.

* Smalltalk distinguishes between global and local variables according
to the case of the first letter.

* Haskell distinguishes between normal functions and constructors
(both data constructors and type constructors) by the case of the
first letter, and has Prolog's `_' convention.

* ML allows a single-quote in variable names, but reserves names
beginning with a single-quote for type variables. It also has
Prolog's `_' convention.
You could add Ruby's naming rules here. Or the very very common
convention of using ALL_UPPER for symbolic constants (or
pseudo-constants as in Python). And *quite a lot* of other either
cross-language or language-specific naming conventions.

Jun 27 '08 #140
Russ P. a écrit :
On Jun 8, 5:40 am, Mark Wooding <m...@distorted.org.ukwrote:
>Russ P. <Russ.Paie...@gmail.comwrote:
>>The idea of being able to discern properties of an object by its name
alone is something that is not normally done in programming in
general.
Really? You obviously haven't noticed Prolog, Smalltalk, Haskell, ML,
or Erlang then. And that's just the ones I can think of off the top of
my head.

* Prolog and Erlang distinguish atoms from variables by the case of
the first letter; also `_' is magical and is equivalent to a new
variable name every time you use it.

* Smalltalk distinguishes between global and local variables according
to the case of the first letter.

* Haskell distinguishes between normal functions and constructors
(both data constructors and type constructors) by the case of the
first letter, and has Prolog's `_' convention.

* ML allows a single-quote in variable names, but reserves names
beginning with a single-quote for type variables. It also has
Prolog's `_' convention.

As far as I can see, discerning properties of a thing from its name
seems relatively common.

Well, "common" in Prolog, Smalltalk, Haskell, ML, and Erlang is hardly
common in general. I'll bet that Java and C/C++ are used more in North
Dakota than all those languages combined are used in the entire world.
And you'll very probably loose.
That's not to say they aren't interesting academic languages, of
course.
Erlang an "academic" language ? Man, you're either a troll or totally
clueless.

Jun 27 '08 #141
Russ P. a écrit :
On Jun 6, 8:25 am, Bruno Desthuilliers <bruno.
42.desthuilli...@websiteburo.invalidwrote:
>>>>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.
Why so ?
Why should the client of a class not be able to declare a *private*
member of the class? You're kidding, right?
I'm dead serious. I often add implementation attributes to either a
class or an instance. These *are* implementation parts, not API.

If a client accesses a data member of a class,
Please stop thinking in C++. This is Python, and all you have are
attributes. Whether they're callable of not doesn't change much here.
then by definition that
member is not really private,
Who cares about it being "private" ? The important point is that it's
*implementation*, not *interface*.
so letting the client create a new data
member and declare it as private seems a bit silly to me.
There are two ways to decorate a class or instance object (nb: Python's
classes are objects too): the "static" way where you wrap the object in
a decorator class or instance and use delegation, and the "dynamic" way
where you just modify the original class or object at runtime. The fact
that an attribute is added (or replaced) outside the class statement
doesn't mean it has to be part of the interface. You sometime have
pretty legitimate reason to modify the implementation at runtime.
Actually,
just letting the client create the new data member, private or not,
seems like a bit of a stretch to me, but I'll leave that be.
You're way too much in the Java/C++ way of thinking.
>>For the record, I have made it abundantly clear that I don't think
Python should not have as rigorous an encapsulation regime as C++ or
Java. The worst that could happen with my proposition is that you
would need to use a "mangled" name to access private data or methods.
That's already the case - when you use __name_mangling. And if there's
no effective access restriction, then what the point of having this
'priv' keyword ?
>>But you will be using the name many times, you can reassign your own
name, of course, so the mangled name need not appear more than once
where it is needed.
Once again, I just don't see the point. Either you want effective access
restriction in Python, or you don't. And if you don't, what would this
'priv' keyword be useful to ?

In the end, I suppose it boils down to aesthetics and personal
preference.

The leading-underscore convention bothers me for two reasons: (1) like
the OP, I don't like the way it makes my code look, and (2) it is a
signal to a person reading the code, but it has no actual effect in
the interpreter.
Indeed. The target of the signal is definitively the person reading the
code.
I think the concept of private data and methods is important enough to
be implemented with more than just a tacky naming convention.
The concept of "private" attributes is not important. What's important
is the concept of implementation attributes.
That is
why I suggested the "priv" keyword. At the same time, I realize that
people will occasionally be frustrated if they are rigorously denied
access to all private data, which is why I suggested an "indirect"
method of access through mangled names.
We already have all this. Either you want language-enforced access
restriction - then you might be happier with another language - or you
just want to have a clear way to know whether an attribute is part of
the API or not - in which case a naming convention is not only enough,
but even better.
You can argue that such indirect access defeats the whole idea of
private data, but at least it alerts the client to the fact that he
(or she or it) is accessing private data
So does the naming convention, with much less work.
-- and it does so without
using Hungarian notation.
I wouldn't label this "hungarian notation" - or at least, not the way
"hungarian notation" is now commonly understood.
I would let the "priv" keyword also be used for data or functions at
file scope. It just seems logical to me. Again, some name mangling
convention could be concocted for those who think they really need
access.

Actually, the whole objection to denied access baffles me a bit.
Free your mind from the very peculiar, restricted and IMHO braindead
conception of "OO" they taught you with Java and C++. Python is older
than Java, it's by now a very very commonly used language on all major
platforms, and experience prooves that you just don't need anything more
than a simple naming convention.
Does
anyone object to not having access from outside a function to local
variables within the function? I doubt it. The other thing is that the
vast majority of Python software, I would guess, is provided with
source code. How many Python applications or libraries are provided
without source code? If you have the source code, you can obviously
just delete the "priv" keyword anywhere or everywhere it appears.
Yes, fine. And then have to maintain a fork of the source code, and
distribute it with the application. Honking great idea. doh :-(
And
if you have a major client who insists on access to all the internals,
just delete all occurrences of "priv" before you ship the code (or
don't use it to start with).
Or don't even bother about this useless access restriction stuff. Which
will save you quite a lot of valuable time.

Jun 27 '08 #142
Mark Wooding a écrit :
Fuzzyman <fu******@gmail.comwrote:
>So, you are stating that no API programmer using Python *ever* has a
valid or genuine reason for wanting (even if he can't have it) genuine
'hiding' of internal state or members from consumers of his (or
her...) API?

I don't want to speak for whoever you were responding to, but from my
point of view...

Yes.

I understand the difference between the documented interface of a system
and the details of its implementation. But sometimes it can be useful
to take advantage of implementation details, particularly if the
published interface is inadequate in some way. Whether or not I choose
to make use of implementation details is a trade-off between immediate
convenience and maintainability, but that's something I can make a
rational decision about.

By enforcing your `data hiding', you're effectively telling me that I'm
too stupid to make rational decisions of this sort. And that's actually
extremely insulting.
I couldn't state it better. +1QOTW btw.

Jun 27 '08 #143
On Jun 9, 2:23 am, Bruno Desthuilliers <bruno.
42.desthuilli...@websiteburo.invalidwrote:
Mark Wooding a écrit :
Fuzzyman <fuzzy...@gmail.comwrote:
So, you are stating that no API programmer using Python *ever* has a
valid or genuine reason for wanting (even if he can't have it) genuine
'hiding' of internal state or members from consumers of his (or
her...) API?
I don't want to speak for whoever you were responding to, but from my
point of view...
Yes.
I understand the difference between the documented interface of a system
and the details of its implementation. But sometimes it can be useful
to take advantage of implementation details, particularly if the
published interface is inadequate in some way. Whether or not I choose
to make use of implementation details is a trade-off between immediate
convenience and maintainability, but that's something I can make a
rational decision about.
By enforcing your `data hiding', you're effectively telling me that I'm
too stupid to make rational decisions of this sort. And that's actually
extremely insulting.

I couldn't state it better. +1QOTW btw.
Please see my previous reply to that post.

Being "insulted" by data hiding is the "QOTW"? I'd call that an insult
to everyone else who has posted on this forum in the past week. Unless
of course you mean "silliest QOTW."
Jun 27 '08 #144
On Jun 9, 2:22 am, Bruno Desthuilliers <bruno.
42.desthuilli...@websiteburo.invalidwrote:
Does
anyone object to not having access from outside a function to local
variables within the function? I doubt it. The other thing is that the
vast majority of Python software, I would guess, is provided with
source code. How many Python applications or libraries are provided
without source code? If you have the source code, you can obviously
just delete the "priv" keyword anywhere or everywhere it appears.
Yes, fine. And then have to maintain a fork of the source code, and
distribute it with the application. Honking great idea. doh :-(
A client who wishes to bypass access restrictions need not maintain
any "fork." If you have access to the source code, removing my
proposed "priv" keyword from an entire library or application is a one-
liner in sed.

If you wish to remove only specific instances of its occurrences, that
is also a trivial matter, and all that needs to be maintained by the
client is a record of which instances were removed. In fact, the
client doesn't even need to do that, because when the next version
comes out they will be reminded very quickly of where they removed
"priv."

But such a client would be a real fool for depending on private data
and/or methods, of course, because those are not part of the public
API and are not guaranteed to remain unchanged. The whole reason for
private data and methods is that they give the developers freedom to
change the implementation without changing the interface.

How about some common sense here. If you, the client, are convinced
that something declared private should really be public, then perhaps
you should contact the developer and explain your reasoning. If the
developer agrees, then the problem is solved. If not, then perhaps it
is *you*, the client who does not understand the proper usage of the
code.

I don't have time to reply to all or your claims, but my lack of a
reply to any particular point should not be construed as implicit
agreement.
Jun 27 '08 #145
On 9 juin, 20:43, "Russ P." <Russ.Paie...@gmail.comwrote:

(snip argument about s/private/public/g on a whole source tree not
being a fork, and not being by far a worse hack than monkeypatching a
small specific part of a whole lib - what can I say ?)
How about some common sense here.
Good question.

But for which definition of "common sense" ? May I remind you that,
for a long time, "common sense" dictated that the earth was flat and
at the center of the universe, and that anything heavier than air
could by no mean fly ? Or, more recently, that their was a market for
at most 5 computers on earth, and that 640kb of RAM ought to be enough
for anyone ?

If you, the client, are convinced
that something declared private should really be public, then perhaps
you should contact the developer and explain your reasoning.
Indeed. At least something we seem to agree on.
If the
developer agrees, then the problem is solved.
Indeed again. But...

But if it takes 6 month to get the mentioned developer to release
something I can use, I'm screwed up. Fine.

As strange as it might be, I prefer to *first* make it work, *then*
contact the developer. And while we're at it:
If not,
Then I prefer to be able to monkeypatch the code and only maintain my
monkeypatch than to have to maintain a whole fork of the original
lib.

But YMMV of course...
then perhaps it
is *you*, the client who does not understand the proper usage of the
code.
Do you really think that I'm fiddling with implementation stuff that
may break my code any other release because I don't *understand* that
code ? But anyway : even if it happened to be the case, it would still
be my own responsability. So what's the matter ? Should we forbid
hammers because you could use one to bang your head with ?
I don't have time to reply to all or your claims, but my lack of a
reply to any particular point should not be construed as implicit
agreement.
Sounds like a lawyer's notice. Anyway, your lack of agreement won't
keep me from happily add implentation attributes to existing objects
whenever I find it appropriate. Sorry for being more on the pragmatic
side than on the cargo-cult one.
Jun 27 '08 #146
On Jun 9, 2:10 pm, "bruno.desthuilli...@gmail.com"
<bruno.desthuilli...@gmail.comwrote:
But if it takes 6 month to get the mentioned developer to release
something I can use, I'm screwed up. Fine.
I've lost track of how many times I've said this now, but my
suggestion for a "priv" keyword allowed for "indirect" access to
private data through some name-mangling scheme. That could be your
temporary fix while you are waiting for the developer to release a
corrected version. And even if that option were not available, you
could simply open up the relevant source file in the editor of your
choice and remove the offending "priv" declaration. I completely fail
to see how you are "screwed."

Sorry, but when I have to keep repeating the same basic points over
and over, I can't help but think I might be wasting my time.

Jun 27 '08 #147
On Jun 9, 10:23*am, Bruno Desthuilliers <bruno.
42.desthuilli...@websiteburo.invalidwrote:
Mark Wooding a écrit :
Fuzzyman <fuzzy...@gmail.comwrote:
So, you are stating that no API programmer using Python *ever* has a
valid or genuine reason for wanting (even if he can't have it) genuine
'hiding' of internal state or members from consumers of his (or
her...) API?
I don't want to speak for whoever you were responding to, but from my
point of view...
Yes.
I understand the difference between the documented interface of a system
and the details of its implementation. *But sometimes it can be useful
to take advantage of implementation details, particularly if the
published interface is inadequate in some way. *Whether or not I choose
to make use of implementation details is a trade-off between immediate
convenience and maintainability, but that's something I can make a
rational decision about.
By enforcing your `data hiding', you're effectively telling me that I'm
too stupid to make rational decisions of this sort. *And that's actually
extremely insulting.

I couldn't state it better. +1QOTW btw.
By telling me that I can never have a valid reason for wanting 'data
hiding' you're effectively telling me that I'm too stupid to make
rational decisions of this sort. And that's actually extremely
insulting.

Fuzzyman
http://www.ironpython.info/
Jun 27 '08 #148
Russ P. a écrit :
On Jun 9, 2:10 pm, "bruno.desthuilli...@gmail.com"
<bruno.desthuilli...@gmail.comwrote:
>But if it takes 6 month to get the mentioned developer to release
something I can use, I'm screwed up. Fine.

I've lost track of how many times I've said this now, but my
suggestion for a "priv" keyword allowed for "indirect" access to
private data through some name-mangling scheme.
And I've lost track of how many times I've said this now, but we already
have this. While we're at it, why not a 'prot' keyword that would
restrict name-mangling to the addition of a single leading underscore ?
That could be your
temporary fix while you are waiting for the developer to release a
corrected version. And even if that option were not available, you
could simply open up the relevant source file in the editor of your
choice and remove the offending "priv" declaration.
Yes. And I can always edit the source code and add the methods I need
etc. You probably never used monkeypatching, so I guess you just can't
understand the difference between maintaining a monkeypatch and
maintaining a fork.
I completely fail
to see how you are "screwed."
Sorry, but when I have to keep repeating the same basic points over
and over, I can't help but think I might be wasting my time.
If you hope to get a general agreement here in favor of a useless
keyword that don't bring anything to the language, then yes, I'm afraid
you're wasting your time.

Jun 27 '08 #149
On Jun 10, 1:04 am, Bruno Desthuilliers <bruno.
42.desthuilli...@websiteburo.invalidwrote:
If you hope to get a general agreement here in favor of a useless
keyword that don't bring anything to the language, then yes, I'm afraid
you're wasting your time.
Actually, what I hope to do is to "take something away" from the
language, and that is the need to clutter my identifiers with leading
underscores.

I find that I spend the vast majority of my programming time working
on the "private" aspects of my code, and I just don't want to look at
leading underscores everywhere. So I usually just leave them off and
resort to a separate user guide to specify the public interface.

I'll bet many Python programmers do the same. How many Python
programmers do you think use leading underscores on every private data
member or method, or even most of them for that matter? I'll bet not
many. (See the original post on this thread.) That means that this
particular aspect of Python is basically encouraging sloppy
programming practices.

What I don't understand is your visceral hostility to the idea of a
"priv" or "private" keyword. If it offends you, you wouldn't need to
use it in your own code. You would be perfectly free to continue using
the leading-underscore convention (unless your employer tells you
otherwise, of course).

I get the impression that Python suits your own purposes and you
really don't care much about what purpose others might have for it. I
am using it to develop a research prototype of a major safety-critical
system. I chose Python because it enhances my productivity and has a
clean syntax, but my prototype will eventually have to be re-written
in another language. I took a risk in choosing Python, and I would
feel better about it if Python would move up to the next level with
more advanced features such as (optional) static typing and private
declarations. But every time I propose something like that, I get all
kinds of flak from people here who do their hacking and care little
about anyone else's needs.

With a few relatively small improvements, Python could expand its
domain considerably and make major inroads into territory that is now
dominated by C++, Java, and other statically compiled languages. But
that won't happen if reactionary hackers stand in the way.

Side note: I've been looking at Scala, and I like what I see. It may
actually be more appropriate for my needs, but I have so much invested
in Python at this point that the switch will not be easy.
Jun 27 '08 #150

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.