473,409 Members | 1,935 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,409 software developers and data experts.

Accessors in Python (getters and setters)

Hello,

What is the Pythonic way of implementing getters and setters. I've
heard
people say the use of accessors is not Pythonic. But why? And what is
the alternative? I refrain from using them because they smell
"Javaish."
But now my code base is expanding and I'm beginning to appreciate the
wisdom behind them. I welcome example code and illustrations.

Regards

Jul 10 '06
112 13709

Bruno Desthuilliers wrote:
mystilleef wrote:
Bruno Desthuilliers wrote:
(snip)
>>>>You use accessors when you need to control access to a data attribute.

Indeed. And when you don't need too ? (the second 'o' is not a typo)

You make the attribute private/protected.

doh :(

Let's talk about psychorigid mindset...

Thanks, I'm insane.

You say so.
(snip)
>>>>>Then why do you advise "(making) all attributes of a class
>private/protected" and systematically using properties ?
>
Because you don't want third parties illegimately tampering with an
object's internal data and thus crashing your system?

Let's try again...

point 1 : there's *no* language-inforced access restriction in Python.
Just a *convention*.

Huh? What are properties for then?

To allow attribute syntax when you really have computation behind. Which
1/ let you start with the simplest case (a simple attribute) and change
your mind latter
2/ offer the possibility to use an attribute syntax (instead of a method
call syntax) when it seems more natural.

Right, and what I'm I trying to do again?

Write Java in Python.
Dude, I haven't written more than "Hello World" programs in Java. I
__don't__ have a strong Java background.
>>>point 2 : so anyone *can* "illegimately tampering with an object's
internal data" at will.
And this is robust how?
You can do just the same in Java or C++.

OMG!

It's common knowledge.
I ask how your solution is robust, and you go off talking about Java
and C++. Quit turning this into a language pissing contest. The hell I
care what Java or C++ does.
>>>point 3 : anyway it's not *my* system that will then crash - but the
system of the one who "illegimately" played with my package's objects
internals. And as far as I'm concerned, it's none of my problem - they
were marked as implementation, so anyone playing with them is on it's
own. FWIW, I suspect that if someone want to muck with implementation,
he certainly has a good legitimate reason to do so, and will do her best
to not break anything. Else he's a complete idiot and there's no cure
for this.

You can't be serious. Please tell me you are joking.

I'm deadly serious and definitively not joking. There's no cure for
idiocy, and there's definitively nothing like an idiot-proof system.
Sure, but calling users idiots for as result of your laziness or poor
design or lack of robustness is equally idiotic.

Ok, then 99.99% of Python programmers are lazy, have poor design skills
and are unable to write a robust application. So they are idiotic too.
If you say so.
>>>point 4 : since we have computed attributes, turning a "public data
attribute" (to use your idiom) into a "private/protected data attribute
with accessors" *without breaking the interface* is not even a non-brainer.

Now, please, can you explain the difference between :

class Complicated(object):
def __init__(self, data):
self.data = data
def _get_data(self):
return self._data
def _set_data(self, data):
self._data = data

and

class Pragmatic(object):
def __init__(self, data)
self.data = data
and find any *valid* reason to use the first solution instead of the
second ? ('that's what the book says' not being a valid reason).

I don't know it's your code not mine.

IOW : you're unable to find any valid reason to use the second solution
instead of the first (of course : there's none), but refuse to admit it.
Hey, I didn't write that code. You did! You deal with it. My input on
__your__ code at this point is irrelevant.

It's totally relevant, and you're still unable to come with any valid
reason to prefer the first solution over the second. I'm totally
confident that if there was *any* defendable reason to favor the first
approach, you'd have chosen to answer instead of playing dumb.
Chosen what answer? First of all, I have no idea what you are trying to
do. Secondly, I wouldn't code like that. So asking for my input on
some code that I believe has no purpose is irrelevant. In your class,
Complicated, why are your accessors private? Why is the attribute the
accessors are modifying public? In your second class, can data afford
to be modified by anyone? Does doing that cause any corruption, bugs,
indiscrepancies in the system? You can't just throw code at me, out of
context, and tell me to choose which is better. It's just premature.
>>class Robust(object):

def __init__(self):
# Arbitrarily changing this state to False will crash app or will
# corrupt the whole event system.
self.__is_active = True

def get_is_active(self):
return self.__is_active

buffer_is_active = property(get_is_active, doc="True if buffer is
editable")

def monitor_events(self):
# Only methods of this class can change __is_active.
# Add code to change __is_active here.
return

Yuck.
See! I'm controlling access.

You are not controlling *anything*

r = Robust()
r._Robust__is_active = True

*sighs*

You keep coming up with these unrealistic and impractically delusional
theories

Pardon ? Which "unrealistic and impractically delusional theories" ?
Please try the code above instead of getting to big words...
Doesn't that fall under the "DO NOT DO THIS AT HOME KIDS" in the FAQ
section or somewhere?
to make yourself feel happy.

yes, of course, I need this to feel happy. Doh :(
Sure Python lets your do that,
but that's an implementation detail almost all Python developers could
give a damn about. How many times do I have to tell you I don't care
for latent semantic implementation details of Python? Anybody who does
what you just did should be laughed at derisively and ignored.

Believe it or not, but there are times someone may have a perfectly
valid reason to do so (probably not with your example, but that's
another point).
I have never seen any Python code do that. I will certainly reject code
like that in my project. But if people do it without any ill effects,
good for them. I don't do it, I don't know any Python developer that
does.
But I
don't have time to deal with fantasy and unreleastic theories.

blah blah.
>As I told you, there's no cure for idiocy.
Whee! And if one sober morning I want to
change the name __is_active to __buffer_is_active, I won't have to hunt
down 27000 lines of code to do it.

And what if you want to change 'buffer_is_active' to 'is_active' ?
But I don't want to. I wanna change implementation not interface.

Changing implementation from direct attribute access to property doesn't
require changing the interface, so there's no reason to use a property
for simple read/write access. period.
There is. The name issues already afore-mentioned elsewhere.
>>Also a naive third party won't crash
my system by changing Robust's state arbitrarily.

Lol. cf above. And, may I repeat : you're getting the "my/3rd part"
stuff the wrong way. If someone uses your code in it's app, then it's
*her* system, and *your* code is the '3rd part'. Whether someone wants
to do idiotic things with your code that will result in a crash is none
of *your* concern. Just like if someone buy a hammer and bangs his head
with, it's not the concern of the guy who made the hammer.
That's just silly. If a third party plugin is crashing your app,

Not my responsability.
You enjoy pointing fingers, don't you?
guess
who's gonna get the emails and bug reports? That's right you!

And ?
You have to investigate it?
And that
is after hours of trying to reproduce the bug on your system
unsuccessfully

If the app runed fine and all of a sudden starts to crash, I'll suspect
something specific to the user system.
There you go again pointing fingers. It has to be the stupid idiotic
users fault.
because you don't have the bloody plug-in installed and
they user doesn't know a random plug-in he downloaded is the root of
the problem.

"Hi Mr User... Just a question about your problem : did you change
anything in your system recently ? Like installing a new plugin ?"
Yeah, now you have 20/20 hindsight.
>
>>Because in the real
world when your program is buggy, you get bug reports, nasty emails
among other forms of ridicule.

So you see receiving a bug report as a form of ridicule ?
Yes, it can be.

I definitively give up trying to understand you.
I guess you haven't got bug reports that make you feel like shit. Only
to find out the problem actually has nothing to do with your app.
>Now FWIW, I have lot of python apps in production, very few bug reports
[1], and none of them being the result of the problem you seems to fear
that much.

Good for you! I'm sure you are brilliant programmer.

I'm not.
>[1] The very first release of one of them is in production for more than
6 monthes now, is daily used by a dozen non-computer-savy users, and not
a *single* bug report - actually, the only return we had is "it's
perfect, it works like a charm, and we have some other stuff for you guys"

My users are not just end users they are also developers.

Developpers are supposed to know enough to fill in useful bug reports...
and possibly do some prior research on the problem by themselves.
Developers extend your application in ways you hadn't originally
anticipated, thus exposing bugs. And no, it's not the developers fault.
I know that's where you are going. There are several reasons why this
can happen, including me not protecting object's state properly. But
we've already been through all that to no avail.
>>And your supposed solution to my problem
is me saying, "but...but...I told you not change is_active."

In my example (which was not intended as a "solution to a problem"),
is_active is clearly part of the API. So your argument is moot.

OTOH, if I need to control access to is_active, I can easily change it's
implementation - ie by using a property (or any custom descriptor). So
my "solution to the problem" is functionally equivalent to yours, and
requires much less code - which contributes to making it more robust.

Your example

Which one ?
actually requires more code,
is looks complex and it's
ugly


You mean:

class Pythonic(object):
def __init__(self):
self._is_active = True

@apply
def is_active():
def fget(self): return self._is_active
def fset(self): raise SomeException('sorry, read-only')
return property(**locals())

(no offense, my opinion).

of course.
Yes, that.
>>Ha! And if
you can't figure out why anyone would do this,

Oh yes, I can :
- too much exposure to B&D languages
- lack of ability to criticize "what's in the Book"
- confusion between state/behaviour concepts and the (mostly inexisting
in most hi-level languages) data/function dichotomy
- control-freak mindset
Lets stick to the arguments please. No need to attack me.

You're of course free to identify yourself with the 'anyone' described
above - but that's your responsability, not mine.
Please, given the wild assumptions you have made about me in this
thread alone, only someone who can't read between the lines would
question who that was directed at.
>>then I'm not wasting my
time here anymore.

You're wasting your time because you refuse to escape from your "what's
in the book" mindest and insist on writing Java in Python. I had the
same problem when I came from Java to Python, then I had the "aha"
moment where I realized I was overdoing it, writing uselessly
complicated code to do simple things that would just have worked without
all this mumbo/jumbo control freak stuff. But it seems you prefer to
stick to your masochistic approach for no other reason than
misunderstood concepts, so we can't help you here.
Fantastically, I have never used Java for any public project. I don't
understand how you reach your faulty assumptions.

Because most of the opinions you expressed so far are usually
symptomatic from a Java exposure. FWIW, the fact that you "never used
Java for any public project" doesn't contradict anything of my above
writing.
They are also symptomatic of Eiffel, Smalltalk, Ada and about 99% of
all OO languages out there. That still doesn't make me a Java junkie.
>
>>Someday you'll learn the hard way.

Lol. I actually did *un*learn the hard way.

Mystilleef, I've started programing 17 years ago, and have done it
professionnaly for almost 10 years now. I do not pretend to be a good
programmer, but please believe that I do know my job. I've read the Book
too, I've tried applying it blindly, then I used my brain. Once you
understand the real reasons behind a "rule", you also understand when
and how to apply or not apply it.
What book are we talking about again? I made these rules from my
experience writing programs in Python, not from any book.

I fail to see how your view of "data = state / methods = behaviour" or
your advice to "make all data attributes private" comes from experience
writing Python code.
Then I can't help you.
There's only
so much books can do when it comes to designing robust software in
practice.

Indeed.
But for a lot of people over here who claim they've been
programming for X number of years, some of them certainly do need to
hit the books again. I don't believe I spent an inordinate amount of
time explaining state and behavior or the benefits or techniques for
reducing coupling or why anyone would need accessors, among other
things.

Do you really believe you taught me anything about these topics ?
No, but I surprised some of the terms I use confuse you. Or why you
would question why anyone would need to use accessors. And that you
consider data hiding and encapsulation harmful and unnecessary.
However, I'll give you the benefit of the doubt. English is my second
language, and when I write in a haste, I tend to express myself poorly.
>
>>Thanks to the people who exposed me to Python's properties.

The problem is that you definitively *failed* to understand how to use
them (or actually how to *not* use them when not needed).
Sure, if it makes you feel better.

Alas, not. Seeing someone inflicting himself pain because of misbelief
or misunderstanding does not "make me feel better". Too bad you take it
this way.
I feel a lot more pain when I have to investigate bugs that I could
have prevented easily if only I had adhered to sound software
engineering principles as opposed to drinking philosophical Kool Aid.
I'm in tune with most of Python's philosophies. But one needs to know
when to make exceptions as opposed to blindly reciting and following
ingrained mantras.

Jul 20 '06 #101
mystilleef wrote:
Bruno Desthuilliers wrote:
>>>>>>point 2 : so anyone *can* "illegimately tampering with an object's
>>internal data" at will.
>>
>
>And this is robust how?
>

You can do just the same in Java or C++.

OMG!

It's common knowledge.
I ask how your solution is robust,
This is definitively not a problem with "my solution". Python has *no*
access restriction. Anyone can do what he wants with any attribute of
your Python classes.
and you go off talking about Java
and C++.
Whose access restriction is Joke.
>
>>>>>>point 3 : anyway it's not *my* system that will then crash - but the
>>system of the one who "illegimately" played with my package's objects
>>internals. And as far as I'm concerned, it's none of my problem - they
>>were marked as implementation, so anyone playing with them is on it's
>>own. FWIW, I suspect that if someone want to muck with implementation,
>>he certainly has a good legitimate reason to do so, and will do her best
>>to not break anything. Else he's a complete idiot and there's no cure
>>for this.
>>
>
>
>You can't be serious. Please tell me you are joking.

I'm deadly serious and definitively not joking. There's no cure for
idiocy, and there's definitively nothing like an idiot-proof system.
Sure, but calling users idiots for as result of your laziness or poor
design or lack of robustness is equally idiotic.

Ok, then 99.99% of Python programmers are lazy, have poor design skills
and are unable to write a robust application. So they are idiotic too.
If you say so.
Logical derivation from your above statement.
>
>>>>>>point 4 : since we have computed attributes, turning a "public data
>>attribute" (to use your idiom) into a "private/protected data attribute
>>with accessors" *without breaking the interface* is not even a non-brainer.
>>
>>Now, please, can you explain the difference between :
>>
>>class Complicated(object):
>>def __init__(self, data):
> self.data = data
>>def _get_data(self):
> return self._data
>>def _set_data(self, data):
> self._data = data
>>
>>and
>>
>>class Pragmatic(object):
>>def __init__(self, data)
> self.data = data
>>
>>
>>and find any *valid* reason to use the first solution instead of the
>>second ? ('that's what the book says' not being a valid reason).
>>
>
>
>I don't know it's your code not mine.

IOW : you're unable to find any valid reason to use the second solution
instead of the first (of course : there's none), but refuse to admit it.
Hey, I didn't write that code. You did! You deal with it. My input on
__your__ code at this point is irrelevant.

It's totally relevant, and you're still unable to come with any valid
reason to prefer the first solution over the second. I'm totally
confident that if there was *any* defendable reason to favor the first
approach, you'd have chosen to answer instead of playing dumb.

Chosen what answer? First of all, I have no idea what you are trying to
do.
Make you understand why, in Python, it is *totally* useless to mark an
attribute as implementation and add read/write accessors to it. But it's
obviously hopeless.
Secondly, I wouldn't code like that. So asking for my input on
some code that I believe has no purpose is irrelevant. In your class,
Complicated, why are your accessors private?
They are not "private", they are implementation details - in this case,
support for a property.
Why is the attribute the
accessors are modifying public?
It is not public, it is marked as implementation detail - in this case,
support for a property.
In your second class, can data afford
to be modified by anyone?
Obviously - just like in the first example.
>Does doing that cause any corruption, bugs,
indiscrepancies in the system? You can't just throw code at me, out of
context, and tell me to choose which is better. It's just premature.
If you are unable to understand such a simple code then you are totally
clueless. Since your are obviously not totally clueless, it's just bad
faith from you. So I'm obviously wasting my time and bandwidth.

(snip)
>>>>>See! I'm controlling access.

You are not controlling *anything*

r = Robust()
r._Robust__is_active = True

*sighs*

You keep coming up with these unrealistic and impractically delusional
theories

Pardon ? Which "unrealistic and impractically delusional theories" ?
Please try the code above instead of getting to big words...

Doesn't that fall under the "DO NOT DO THIS AT HOME KIDS" in the FAQ
section or somewhere?
Nope. It falls under the "dont do this unless you really need to and
know exactly what you are doing and accept all possible consequences -
IOW you're on your own" section.
>>
>>>Sure Python lets your do that,
but that's an implementation detail almost all Python developers could
give a damn about. How many times do I have to tell you I don't care
for latent semantic implementation details of Python? Anybody who does
what you just did should be laughed at derisively and ignored.

Believe it or not, but there are times someone may have a perfectly
valid reason to do so (probably not with your example, but that's
another point).
I have never seen any Python code do that.
I have.
I will certainly reject code
like that in my project.
But if people do it without any ill effects,
good for them. I don't do it, I don't know any Python developer that
does.
Never heard of the sys._getframe() hack ?
>>>>
>Whee! And if one sober morning I want to
>change the name __is_active to __buffer_is_active, I won't have to hunt
>down 27000 lines of code to do it.

And what if you want to change 'buffer_is_active' to 'is_active' ?
But I don't want to. I wanna change implementation not interface.

Changing implementation from direct attribute access to property doesn't
require changing the interface, so there's no reason to use a property
for simple read/write access. period.


There is. The name issues already afore-mentioned elsewhere.
Lol. The "name issue" you talk about is
1/ exactly a case of changing *interface*
2/ only due to the fact that you're confusing state with non-callable
attributes.
>>>>>Also a naive third party won't crash
>my system by changing Robust's state arbitrarily.

Lol. cf above. And, may I repeat : you're getting the "my/3rd part"
stuff the wrong way. If someone uses your code in it's app, then it's
*her* system, and *your* code is the '3rd part'. Whether someone wants
to do idiotic things with your code that will result in a crash is none
of *your* concern. Just like if someone buy a hammer and bangs his head
with, it's not the concern of the guy who made the hammer.
That's just silly. If a third party plugin is crashing your app,

Not my responsability.


You enjoy pointing fingers, don't you?
Nope. But I refuse to be responsible for someone else's stupidity
(unless this 'someone else' happens to be my son).
>
>>>guess
who's gonna get the emails and bug reports? That's right you!

And ?
You have to investigate it?

>>>And that
is after hours of trying to reproduce the bug on your system
unsuccessfully

If the app runed fine and all of a sudden starts to crash, I'll suspect
something specific to the user system.
There you go again pointing fingers. It has to be the stupid idiotic
users fault.
Your words. Not mines. As far as I'm concerned, I can accept that some
change in the user's environment can impact my program - sometimes in
very very strange ways. I've had a case recently involving Trac, SQLite,
mod_python and PHP5.
>
>>>because you don't have the bloody plug-in installed and
they user doesn't know a random plug-in he downloaded is the root of
the problem.

"Hi Mr User... Just a question about your problem : did you change
anything in your system recently ? Like installing a new plugin ?"
Yeah, now you have 20/20 hindsight.
Of course - I cheated. At least with the last question. But FWIW, if my
app was pluggable and I had a similar case, one of the very first thing
I'd ask would be the detailed and exhaustive list of installed plugins.
>>>>>Because in the real
>world when your program is buggy, you get bug reports, nasty emails
>among other forms of ridicule.

So you see receiving a bug report as a form of ridicule ?
Yes, it can be.

I definitively give up trying to understand you.


I guess you haven't got bug reports that make you feel like shit.
No. I don't allow a bug report to "make me feel like shit". I sometimes
felt really dumb and sorry when I found out how evident the bug was, but
that's another problem.

(snip)
>>>My users are not just end users they are also developers.

Developpers are supposed to know enough to fill in useful bug reports...
and possibly do some prior research on the problem by themselves.
Developers extend your application in ways you hadn't originally
anticipated, thus exposing bugs.
I know, I do a lot of work on existing apps so they fit my customers needs.
And no, it's not the developers fault.
Which developper ? The author of the app, or the one extending it ?
I know that's where you are going. There are several reasons why this
can happen, including me not protecting object's state properly.
If you exposed as part of the interface some highly critical attribute
then yes, you are responsible. If it's the other developper messing with
your implementation, then it's by no way your responsability - but it
may be a sign that your code could need some support for a use case you
had not anticipated.

(snip)
>>>
Your example

Which one ?

>>>actually requires more code,
is looks complex and it's
ugly


You mean:

class Pythonic(object):
def __init__(self):
self._is_active = True

@apply
def is_active():
def fget(self): return self._is_active
def fset(self): raise SomeException('sorry, read-only')
return property(**locals())
(snip)
Yes, that.
Then you find Python complex and ugly. But what I find surprising is
that you could make a judgement on "my example" before I wrote it...
(snip)
>>>What book are we talking about again? I made these rules from my
experience writing programs in Python, not from any book.

I fail to see how your view of "data = state / methods = behaviour" or
your advice to "make all data attributes private" comes from experience
writing Python code.

Then I can't help you.
That's an understatement.
>>>But for a lot of people over here who claim they've been
programming for X number of years, some of them certainly do need to
hit the books again. I don't believe I spent an inordinate amount of
time explaining state and behavior or the benefits or techniques for
reducing coupling or why anyone would need accessors, among other
things.

Do you really believe you taught me anything about these topics ?


No, but I surprised some of the terms I use confuse you.
The only term that confused me was actually "contaminated".
Or why you
would question why anyone would need to use accessors.
Where did I question this ? Chapter and verse, please.
And that you
consider data hiding and encapsulation harmful and unnecessary.
I consider language-inforced access restriction as harmful and
unnecessary. And it has very few to do with encapsulation.
However, I'll give you the benefit of the doubt.
How nice from you. But given the views you expressed about "sound
software engineering principles" and your understanding of concepts such
as state, behaviour, coupling and encapsulation, please consider me as
definitively wasted.
>>>>>Thanks to the people who exposed me to Python's properties.

The problem is that you definitively *failed* to understand how to use
them (or actually how to *not* use them when not needed).
Sure, if it makes you feel better.

Alas, not. Seeing someone inflicting himself pain because of misbelief
or misunderstanding does not "make me feel better". Too bad you take it
this way.


I feel a lot more pain when I have to investigate bugs that I could
have prevented easily if only I had adhered to sound software
engineering principles as opposed to drinking philosophical Kool Aid.
Exactly. Here, the "sound software engineering principles" is to pay a
minimal attention to naming of interface elements, and the
"philosophical Kool Aid" confusing non-callable attributes with
implementation detail.
I'm in tune with most of Python's philosophies. But one needs to know
when to make exceptions as opposed to blindly reciting and following
ingrained mantras.
Exact once again. Here, the mantra is "state is data is private,
behaviour is method is public". That may be true for Smalltalk, but not
for Python.
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 20 '06 #102
Ant
Came across this article this afternoon - thought it may be of interest
to some of those following this thread...

http://www.devx.com/opensource/Article/31593/0/page/2

Jul 20 '06 #103
On 2006-07-20 09:40:31, Bruno Desthuilliers wrote:
>I'm not sure, but there's one thing that has a potential to be the real
issue: what's the common way to create a property that is read-write
for the implementation and "read-only" for the interface?

class Foo(object):
@apply
def _imp():
def fget(self):
# code here
def fset(self, val):
# code here
return property(**locals())

@apply
def api():
def fget(self):
return self._imp
def fset(self, val):
raise SomeException('read-only, sorry')
return property(**locals())
Thanks a lot. This looks similar to what Steve Holden wrote. (And yes,
Steve, you understood exactly what I meant :)

My hunch is that this is what mystilleef might have wanted to say all
along; it looks quite similar to what he seemed to try to express. It's
basically the Python synonym of creating a public accessor (api) for a
private attribute (_imp) -- in this case to make the API read-only while
maintaining the implementation read-write, but I'm sure there are other
uses for such a structure.

Note that a read-only property named 'is_active' returning the value of
an attribute named '_is_active' doesn't prevent direct access to
'_is_active' attribute, neither from the class nor from the client code.
Right; I already understood that :)

I just thought one part of this whole thread was that accessors are not
necessary in Python. However, it seems that this case -- different
restrictions (or actions) for access from implementation vs through the API
(which is probably one of the most common reasons for using accessors in
other languages) -- in Python also can only be handled by adding a separate
accessor. (This of course in Python is implemented as a computed
attribute.)

The above illustrated technique doesn't look so different from a C++ or
Java code with public set/getApi() accessors acting on a private imp
attribute (or public set/getIsActive() accessors acting on a private
isActive attribute -- to use the other, similar example that operates with
the names this thread likes to use :)

Do I seem to understand this correctly?

Thanks,
Gerhard

Jul 20 '06 #104

Bruno Desthuilliers wrote:
mystilleef wrote:
Bruno Desthuilliers wrote:
>>>>>point 2 : so anyone *can* "illegimately tampering with an object's
>internal data" at will.
>

And this is robust how?
You can do just the same in Java or C++.

OMG!

It's common knowledge.
I ask how your solution is robust,

This is definitively not a problem with "my solution". Python has *no*
access restriction. Anyone can do what he wants with any attribute of
your Python classes.
and you go off talking about Java
and C++.

Whose access restriction is Joke.
>>>>>point 3 : anyway it's not *my* system that will then crash - but the
>system of the one who "illegimately" played with my package's objects
>internals. And as far as I'm concerned, it's none of my problem - they
>were marked as implementation, so anyone playing with them is on it's
>own. FWIW, I suspect that if someone want to muck with implementation,
>he certainly has a good legitimate reason to do so, and will do her best
>to not break anything. Else he's a complete idiot and there's no cure
>for this.
>
You can't be serious. Please tell me you are joking.

I'm deadly serious and definitively not joking. There's no cure for
idiocy, and there's definitively nothing like an idiot-proof system.
Sure, but calling users idiots for as result of your laziness or poor
design or lack of robustness is equally idiotic.

Ok, then 99.99% of Python programmers are lazy, have poor design skills
and are unable to write a robust application. So they are idiotic too.
If you say so.

Logical derivation from your above statement.
>>>>>point 4 : since we have computed attributes, turning a "public data
>attribute" (to use your idiom) into a "private/protected data attribute
>with accessors" *without breaking the interface* is not even a non-brainer.
>
>Now, please, can you explain the difference between :
>
>class Complicated(object):
>def __init__(self, data):
self.data = data
>def _get_data(self):
return self._data
>def _set_data(self, data):
self._data = data
>
>and
>
>class Pragmatic(object):
>def __init__(self, data)
self.data = data
>
>
>and find any *valid* reason to use the first solution instead of the
>second ? ('that's what the book says' not being a valid reason).
>
I don't know it's your code not mine.

IOW : you're unable to find any valid reason to use the second solution
instead of the first (of course : there's none), but refuse to admit it.
Hey, I didn't write that code. You did! You deal with it. My input on
__your__ code at this point is irrelevant.

It's totally relevant, and you're still unable to come with any valid
reason to prefer the first solution over the second. I'm totally
confident that if there was *any* defendable reason to favor the first
approach, you'd have chosen to answer instead of playing dumb.
Chosen what answer? First of all, I have no idea what you are trying to
do.

Make you understand why, in Python, it is *totally* useless to mark an
attribute as implementation and add read/write accessors to it. But it's
obviously hopeless.
Secondly, I wouldn't code like that. So asking for my input on
some code that I believe has no purpose is irrelevant. In your class,
Complicated, why are your accessors private?

They are not "private", they are implementation details - in this case,
support for a property.
Why is the attribute the
accessors are modifying public?

It is not public, it is marked as implementation detail - in this case,
support for a property.
In your second class, can data afford
to be modified by anyone?

Obviously - just like in the first example.
Does doing that cause any corruption, bugs,
indiscrepancies in the system? You can't just throw code at me, out of
context, and tell me to choose which is better. It's just premature.

If you are unable to understand such a simple code then you are totally
clueless. Since your are obviously not totally clueless, it's just bad
faith from you. So I'm obviously wasting my time and bandwidth.

(snip)
>>>>See! I'm controlling access.

You are not controlling *anything*

r = Robust()
r._Robust__is_active = True

*sighs*

You keep coming up with these unrealistic and impractically delusional
theories

Pardon ? Which "unrealistic and impractically delusional theories" ?
Please try the code above instead of getting to big words...
Doesn't that fall under the "DO NOT DO THIS AT HOME KIDS" in the FAQ
section or somewhere?

Nope. It falls under the "dont do this unless you really need to and
know exactly what you are doing and accept all possible consequences -
IOW you're on your own" section.
>
Sure Python lets your do that,
but that's an implementation detail almost all Python developers could
give a damn about. How many times do I have to tell you I don't care
for latent semantic implementation details of Python? Anybody who does
what you just did should be laughed at derisively and ignored.

Believe it or not, but there are times someone may have a perfectly
valid reason to do so (probably not with your example, but that's
another point).
I have never seen any Python code do that.

I have.
I will certainly reject code
like that in my project.
But if people do it without any ill effects,
good for them. I don't do it, I don't know any Python developer that
does.

Never heard of the sys._getframe() hack ?
>>>
Whee! And if one sober morning I want to
change the name __is_active to __buffer_is_active, I won't have to hunt
down 27000 lines of code to do it.

And what if you want to change 'buffer_is_active' to 'is_active' ?
But I don't want to. I wanna change implementation not interface.

Changing implementation from direct attribute access to property doesn't
require changing the interface, so there's no reason to use a property
for simple read/write access. period.

There is. The name issues already afore-mentioned elsewhere.

Lol. The "name issue" you talk about is
1/ exactly a case of changing *interface*
2/ only due to the fact that you're confusing state with non-callable
attributes.
>>>>Also a naive third party won't crash
my system by changing Robust's state arbitrarily.

Lol. cf above. And, may I repeat : you're getting the "my/3rd part"
stuff the wrong way. If someone uses your code in it's app, then it's
*her* system, and *your* code is the '3rd part'. Whether someone wants
to do idiotic things with your code that will result in a crash is none
of *your* concern. Just like if someone buy a hammer and bangs his head
with, it's not the concern of the guy who made the hammer.
That's just silly. If a third party plugin is crashing your app,

Not my responsability.

You enjoy pointing fingers, don't you?

Nope. But I refuse to be responsible for someone else's stupidity
(unless this 'someone else' happens to be my son).
>>guess
who's gonna get the emails and bug reports? That's right you!

And ?
You have to investigate it?

>>And that
is after hours of trying to reproduce the bug on your system
unsuccessfully

If the app runed fine and all of a sudden starts to crash, I'll suspect
something specific to the user system.
There you go again pointing fingers. It has to be the stupid idiotic
users fault.

Your words. Not mines. As far as I'm concerned, I can accept that some
change in the user's environment can impact my program - sometimes in
very very strange ways. I've had a case recently involving Trac, SQLite,
mod_python and PHP5.
>>because you don't have the bloody plug-in installed and
they user doesn't know a random plug-in he downloaded is the root of
the problem.

"Hi Mr User... Just a question about your problem : did you change
anything in your system recently ? Like installing a new plugin ?"
Yeah, now you have 20/20 hindsight.

Of course - I cheated. At least with the last question. But FWIW, if my
app was pluggable and I had a similar case, one of the very first thing
I'd ask would be the detailed and exhaustive list of installed plugins.
>>>>Because in the real
world when your program is buggy, you get bug reports, nasty emails
among other forms of ridicule.

So you see receiving a bug report as a form of ridicule ?
Yes, it can be.
I definitively give up trying to understand you.

I guess you haven't got bug reports that make you feel like shit.

No. I don't allow a bug report to "make me feel like shit". I sometimes
felt really dumb and sorry when I found out how evident the bug was, but
that's another problem.

(snip)
>>My users are not just end users they are also developers.

Developpers are supposed to know enough to fill in useful bug reports...
and possibly do some prior research on the problem by themselves.
Developers extend your application in ways you hadn't originally
anticipated, thus exposing bugs.

I know, I do a lot of work on existing apps so they fit my customers needs.
And no, it's not the developers fault.

Which developper ? The author of the app, or the one extending it ?
I know that's where you are going. There are several reasons why this
can happen, including me not protecting object's state properly.

If you exposed as part of the interface some highly critical attribute
then yes, you are responsible. If it's the other developper messing with
your implementation, then it's by no way your responsability - but it
may be a sign that your code could need some support for a use case you
had not anticipated.

(snip)
>>
Your example

Which one ?
actually requires more code,
is looks complex and it's
ugly
You mean:

class Pythonic(object):
def __init__(self):
self._is_active = True

@apply
def is_active():
def fget(self): return self._is_active
def fset(self): raise SomeException('sorry, read-only')
return property(**locals())
(snip)
Yes, that.

Then you find Python complex and ugly. But what I find surprising is
that you could make a judgement on "my example" before I wrote it...
(snip)
>>What book are we talking about again? I made these rules from my
experience writing programs in Python, not from any book.

I fail to see how your view of "data = state / methods = behaviour" or
your advice to "make all data attributes private" comes from experience
writing Python code.
Then I can't help you.

That's an understatement.
>>But for a lot of people over here who claim they've been
programming for X number of years, some of them certainly do need to
hit the books again. I don't believe I spent an inordinate amount of
time explaining state and behavior or the benefits or techniques for
reducing coupling or why anyone would need accessors, among other
things.

Do you really believe you taught me anything about these topics ?

No, but I surprised some of the terms I use confuse you.

The only term that confused me was actually "contaminated".
Or why you
would question why anyone would need to use accessors.

Where did I question this ? Chapter and verse, please.
And that you
consider data hiding and encapsulation harmful and unnecessary.

I consider language-inforced access restriction as harmful and
unnecessary. And it has very few to do with encapsulation.
However, I'll give you the benefit of the doubt.

How nice from you. But given the views you expressed about "sound
software engineering principles" and your understanding of concepts such
as state, behaviour, coupling and encapsulation, please consider me as
definitively wasted.
>>>>Thanks to the people who exposed me to Python's properties.

The problem is that you definitively *failed* to understand how to use
them (or actually how to *not* use them when not needed).
Sure, if it makes you feel better.

Alas, not. Seeing someone inflicting himself pain because of misbelief
or misunderstanding does not "make me feel better". Too bad you take it
this way.

I feel a lot more pain when I have to investigate bugs that I could
have prevented easily if only I had adhered to sound software
engineering principles as opposed to drinking philosophical Kool Aid.

Exactly. Here, the "sound software engineering principles" is to pay a
minimal attention to naming of interface elements, and the
"philosophical Kool Aid" confusing non-callable attributes with
implementation detail.
I'm in tune with most of Python's philosophies. But one needs to know
when to make exceptions as opposed to blindly reciting and following
ingrained mantras.

Exact once again. Here, the mantra is "state is data is private,
behaviour is method is public". That may be true for Smalltalk, but not
for Python.
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"

You win!

Bye all, and thanks for your time and insights.

Cheers

Jul 20 '06 #105
Diez B. Roggisch <de***@nospam.web.dewrote:
>Java is not an acronym. That is: it's "Java", not "JAVA".

Now THAT was an important information RIGHT on topic.
It was not meant offensively.
>Java does not allow access to private members via reflection.

For somebody nitpicking on natural language usage to a non-native
speaker, you show an impressive lack of knowledge in the actual subject
discussed.
Again: It was not meant offensively.

Maybe you can try turning the flames down a bit.
http://www.onjava.com/pub/a/onjava/2...eflection.html
Does that approach work on sealed jars as well? I would imagine any
jars that need any kind of "real" security would be sealed...
Jul 20 '06 #106
Diez B. Roggisch a écrit :
>You mean:

class Pythonic(object):
def __init__(self):
self._is_active = True

@apply
def is_active():
def fget(self): return self._is_active
def fset(self): raise SomeException('sorry, read-only')
return property(**locals())


Neat!
http://wiki.python.org/moin/PythonDecoratorLibrary
That slipped my attention over all this noisy and pointless
discussion...
indeed.
Jul 20 '06 #107
Gerhard Fiedler a écrit :
On 2006-07-20 09:40:31, Bruno Desthuilliers wrote:

>>>I'm not sure, but there's one thing that has a potential to be the real
issue: what's the common way to create a property that is read-write
for the implementation and "read-only" for the interface?

class Foo(object):
@apply
def _imp():
def fget(self):
# code here
def fset(self, val):
# code here
return property(**locals())

@apply
def api():
def fget(self):
return self._imp
def fset(self, val):
raise SomeException('read-only, sorry')
return property(**locals())


Thanks a lot. This looks similar to what Steve Holden wrote.
It's of course based on the same principle - which I bet is a very
common pattern in Python[1]. The main difference with Steve's code is
that I took your requirement almost to the letter: there are actually 2
properties, one marked as implementation and read/write, the other
public and read-only returning the value of the first one.
[1] could almost justify a PEP for a builtin ReadOnlyAttribute descriptor...
(And yes,
Steve, you understood exactly what I meant :)

My hunch is that this is what mystilleef might have wanted to say all
along; it looks quite similar to what he seemed to try to express. It's
basically the Python synonym of creating a public accessor (api) for a
private attribute (_imp) --
It's probably the primary use case for properties. But it would be
definitively useless to do so if what you want is read-write access.
in this case to make the API read-only while
maintaining the implementation read-write,
read-write but computed. The most common case (where the r/w
implementation attribute needs no computation) is solved by Steve's example.
but I'm sure there are other
uses for such a structure.
>>Note that a read-only property named 'is_active' returning the value of
an attribute named '_is_active' doesn't prevent direct access to
'_is_active' attribute, neither from the class nor from the client code.


Right; I already understood that :)

I just thought one part of this whole thread was that accessors are not
necessary in Python.
they are not necessary for full read-write access to an existing attribute.
However, it seems that this case -- different
restrictions (or actions) for access from implementation vs through the API
(which is probably one of the most common reasons for using accessors in
other languages) -- in Python also can only be handled by adding a separate
accessor. (This of course in Python is implemented as a computed
attribute.)

The above illustrated technique doesn't look so different from a C++ or
Java code with public set/getApi() accessors acting on a private imp
attribute (or public set/getIsActive() accessors acting on a private
isActive attribute -- to use the other, similar example that operates with
the names this thread likes to use :)
The two mains differences are:
- no need to write the accessors if all they do is get/set a variable
- keep an attribute access syntax

Else, no, there's no fundamental difference.
Do I seem to understand this correctly?
Looks like.

Jul 20 '06 #108
Dennis Lee Bieber a écrit :
On Thu, 20 Jul 2006 12:52:52 +0200, Bruno Desthuilliers
<on***@xiludom.grodeclaimed the following in comp.lang.python:

>>Granted. Actually, it *was* a typo - but it happened to also make sens,
so I decided it was not a typo !-)

Ah... One of those "it's faster to just continue typing than to
break my flow and go backwards" moments. <G>
Almost... I noticed it while re-reading.
(and I forgot to include
the <Gon my prior post)
We won't hold it against you !-)
Jul 20 '06 #109
Ant a écrit :
Came across this article this afternoon - thought it may be of interest
to some of those following this thread...

http://www.devx.com/opensource/Article/31593/0/page/2
Yeah. Presenting name mangling as the usual way to have 'private'
attributes, then implementing (costly) access restriction by using... an
implementation detail of the sys module. Great.
Jul 20 '06 #110

Ed Jensen wrote:
Diez B. Roggisch <de***@nospam.web.dewrote:
Ah, you mean like in JAVA

Java is not an acronym. That is: it's "Java", not "JAVA".
where the compiler prevents you from accessing
private variables, but the runtime allows access to these very variables
via reflection?

Java does not allow access to private members via reflection.
Actually it does.

Jul 21 '06 #111
Ed Jensen schrieb:
Diez B. Roggisch <de***@nospam.web.dewrote:
>>Java is not an acronym. That is: it's "Java", not "JAVA".
Now THAT was an important information RIGHT on topic.

It was not meant offensively.
Ok.

>>Java does not allow access to private members via reflection.
For somebody nitpicking on natural language usage to a non-native
speaker, you show an impressive lack of knowledge in the actual subject
discussed.

Again: It was not meant offensively.

Maybe you can try turning the flames down a bit.
I'll try.
>http://www.onjava.com/pub/a/onjava/2...eflection.html

Does that approach work on sealed jars as well? I would imagine any
jars that need any kind of "real" security would be sealed...
Well, lets put it like this: I work for a Java (see, I'm capable of
learning... :)) shop. We deploy pretty large clustered J2EE thingies. In
the last five years working there, I never once produced a sealed jar.

And actually the use-case for a sealed jar is to allow _more_ in an
otherwise restricted environment.

Which puts us to the next question: the sealing itself doesn't do
anything to restrict the code, the SecurityManager does. Which AFAIK is
something hooked into the VM. Now, I'm not on sure grounds here on how
to altere its behaviour, but I'd say if we're talking me working on a
secure application that introduces its own SecurityManager, I'm still
the one in control. I could use your lib, turn off privacy, and fiddle
around.

If things were the other way round, and I'd have to work in a restricted
context, it actually might be that someone restricted private access
(because he owns the VM!). But then - he'd also be able to forbid
threading or file access or all kinds of things that I'd otherwise be
used to work with which will suddenly make my code burst in flames.

And if we are honest: the most problematic cases of abused code arenÄT
the ones of strangers exploiting your code, but instead your fellow
coders at the other department. Which most probably means that they
aren't restrained by security management anyway.

To summarize: it might be possible to jump through a few hoops to
increase the security. But in 99.9% of cases this doesn't happen, as it
would increase complexity by orders of magnitude - for a comparatively
small gain (talking about private declarations. The sandbox-restrictions
of Java for running applets certainly are worth it).

Diez
Jul 21 '06 #112
Diez B. Roggisch <de***@nospam.web.dewrote:
Which puts us to the next question: the sealing itself doesn't do
anything to restrict the code, the SecurityManager does. Which AFAIK is
something hooked into the VM. Now, I'm not on sure grounds here on how
to altere its behaviour, but I'd say if we're talking me working on a
secure application that introduces its own SecurityManager, I'm still
the one in control. I could use your lib, turn off privacy, and fiddle
around.

If things were the other way round, and I'd have to work in a restricted
context, it actually might be that someone restricted private access
(because he owns the VM!). But then - he'd also be able to forbid
threading or file access or all kinds of things that I'd otherwise be
used to work with which will suddenly make my code burst in flames.

And if we are honest: the most problematic cases of abused code aren't
the ones of strangers exploiting your code, but instead your fellow
coders at the other department. Which most probably means that they
aren't restrained by security management anyway.

To summarize: it might be possible to jump through a few hoops to
increase the security. But in 99.9% of cases this doesn't happen, as it
would increase complexity by orders of magnitude - for a comparatively
small gain (talking about private declarations. The sandbox-restrictions
of Java for running applets certainly are worth it).
Interesting stuff! And thanks for the link from your earlier post.

Where I work, this little discovery will actually help us stop jumping
through some hoops we've been jumping through to unit test private
methods.

It also gives us more to think about since we had been assuming
private could not be circumvented.

Thanks Diez. :)
Jul 21 '06 #113

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

Similar topics

10
by: Zap | last post by:
Widespread opinion is that public data members are evil, because if you have to change the way the data is stored in your class you have to break the code accessing it, etc. After reading this...
21
by: Raj | last post by:
Hi, We just executed a project with Python using TG. The feedback was to use more python like programming rather than C style code executed in Python. The feedback is from a Python purist and...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

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.