473,408 Members | 2,813 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,408 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 13708
mystilleef wrote:
Ant wrote:
>>We seem to be flogging a dead horse now. Is the following a fair
summary:

Q. What is the Pythonic way of implementing getters and setters?

A. Use attributes.

Quote: "I put a lot more effort into choosing method and function
names"

Wisdom: Python is a different paradigm from (e.g.) Java w.r.t.
accessors: Put the effort you would have put into choosing accessor
names into choosing attribute names.

Anything else to add to this? Or can it be put to bed?


Here are the lessons I've learned (the hard way).

1) Make all attributes of a class private or protected.
Unless they are obviously part of the implementation (ie: when you would
definitively had written getters/setters in Java), in which case make
them public (and name them with the same care you would have for Java
getters/setters). You can change the implementation later.
You can make
them public later if need be. If anyone tells you making attributes
private/protected is not Pythonic ignore them.
Don't. Just make sure you have the right *API*.
You'll thank me when
your code base grows.
Unless everybody ditch your code and roll their own because they are
bored with coding Java in Python.
2) If a data attribute might likely be an API, think about controlling
access to via "properties".
If you need to control anything - else just use a plain attribute.
That's the pythonic way to implement
accessors and mutators

I guess people who've done medium to large scale programming in Python
already know this.
Do 50+ KLOC count as "medium to large scale" here ?

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 13 '06 #51
Gerhard Fiedler <ge*****@gmail.comwrote:
On 2006-07-13 01:50:18, Alex Martelli wrote:
I'm not sure about which languages you are talking (pretty much all that
allow public methods also allow public attributes), [...]
Smalltalk is a very well known object-oriented language that behaves
otherwise, just as one example.

I didn't know that Smalltalk allows any methods at all... I wrote about
languages that allow public methods, and I didn't think of Smalltalk
falling into that category.
??? Smalltalk ONLY has methods -- no other "functions" or "procedures",
ONLY "methods". The one and only way you interact with an object is by
sending it a message to invoke a method -- that's what's known in most
other languages as "calling a method" (or "calling a function"). And
there is no such thing as a "nonpublic" method either, AFAIK (my
Smalltalk may be rusty, but there surely weren't in the Smalltalk I
learned years ago).
Alex
Jul 13 '06 #52
mystilleef wrote:
(snip)
>
Okay, I feel I need to make myself clear. I certainly I'm not blaming
Python for my mistakes. And I don't think language X is better than
Python or vice-versa. Okay scrap the vice-versa. It was silly of me to
name the variable tmp regardless of whatever excuses I have. This also
doesn't mean in the future I wouldn't use shitty names for my
attributes. :-) I most likely will. But at least now I know how to
minimize its impact of such carelessness. I mentioned them above but I
repeat it hear again.

1). Make all attributes of a class private/protected .
Please re-read my answer to your previous mention of this and my other
remarks in this thread (and below in this thread) about the profound
differences between Python and Java wrt/ object model and attribute
access semantics.
2). If a "non-callable" attribute is going to be used outside a class,
think about making it a property
Unless you don't need to.
and name the property well,
Indeed !-)
Other than that we are just arguing semantics of language. For example,
your view of objects is by categorizing its attributes in callable and
non-callable.
And also API/implementation. These are to orthogonal problems - even in
Java FWIW !-)
However, my categorization is state(data) and
behavior(methods).
If properties are an equivalent of getters/setters, are properties state
or behaviour ? According to your views, they are behaviour, if I
understood you. In that case, what's the difference between 'directely'
(which in fact implies going thru __getattribute__) accessing a public
"data" attribute and accessing an implementation attribute by the mean
of a descriptor (property or custom) ?

* before:

# mylib.py
class Knight(object):
def __init__(self, name):
self.name = name

def sayHello(self):
print "hello, I'm %s" % self.name

# mymain.py
from mylib import Knight
k = Knight("Robin")
print k.name
k.sayHello()
k.name = "Lancelot"
k.sayHello()

* after
# mylib.py
class Knight(object):
def __init__(self, name):
self.name = name

@apply
def name():
def fget(self):
return self._xxx.capitalize()

def fset(self, name):
self._xxx = name

def sayHello(self):
print "hello, I'm %s" % self.name

# mymain.py
from mylib import Knight
k = Knight("Robin")
print k.name
k.sayHello()
k.name = "Lancelot"
k.sayHello()
Neither ways of thinking about it is wrong.
From the client code (including other methods of the same class) POV, is
Knight.name behaviour or state ? Please, don't see it as a flame or a
pissing context or whatever, and try to seriously answer this question.

Thinking in terms of state and behaviour is certainly not wrong in
itself, but what is state and what is behaviour ? If I pass a callable
as an argument to another callable, is the first one data or behaviour ?
If I return a callable from a another callable, is the first callable
data or behaviour ? In a Partial application object [1], is the stored
callable data or behaviour ? Is the class of an object data or
behaviour? Is it's metaclass data or behaviour ?

[1] http://www.python.org/dev/peps/pep-0309/

It just
reflects the way we design classes. When I'm coding I certainly don't
care about how Python accesses tmp.
Neither do I. But I have in mind how I can change the way it is accessed.
What I do care about is how to
change tmp without breaking code left, right and center and the
facilities Python provides for making my code robust.
cf Simon's answer and mines. But your original problem is not related to
tmp being callable or not, it's related to how you use to think about
them, hence name them.
Most other OO
languages provide accessors in addition to keywords for that kind of
stuff.
Most OO languages *don't* provide you accessors - they indeed *forces
you* to write them even for the most trivial cases. What Python (or any
other language supporting "computed attributes" syntax) gives you is a
way to avoid writing tedious, boilerplate code. Not more, not less.
I knew it wasn't Pythonic, but I wanted to know the Pythonic way
to do it. So I asked. My query does not automatically suggest Python
sucks. Neither those it suggest that Java or other OO languages are
better. I asked because I sincerely wanted to know the Pythonic way
handling issues like that.
Mark as implementation what is obviously implementation (be it callable
or not), mark as API what is obviously API (be it callable or not). In
both cases, there will be simple ways to either expose an implementation
name or make a non-callable attribute a property. And *always* try to be
careful about naming, at least (but not restricted to) wrt/ your API.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 13 '06 #53

mystilleef wrote:
Fredrik Lundh wrote:
"mystilleef" wrote:
Pretending to be intelligent does, however.
so the real reason you've written a few hundred posts saying basically "I pick
bad names, which proves... uh... whatever" is to impress people by pretending
to be something you're not ?

</F>

Choosing bad identifiers is not a measure of intelligence. Given your
standing in the Python community, I expect more from you. If your only
contribution to this thread is snide and derisive remarks,
Which, excepting silence, is the best response a troll.
Carl Banks

Jul 13 '06 #54
mystilleef wrote:
Marc 'BlackJack' Rintsch wrote:
>>In <11**********************@35g2000cwc.googlegroups. com>, mystilleef
wrote:

>>>Maric Michaud wrote:

But that's not python philosophy.

Python doesn't have any philosophy with regards to naming identifiers.

But the python community has one. Pythonistas prefer readable source code
so they tend to think about good names. As The Zen of Python says
"Readability counts."

I'm glad I'm in tune with the "python community."
>>>>But they are in Python and that is the python's philosophy. All attribute or
method not beginning with an '_' *is* API.

Right, and what if I want to change a private API to a public one. How
does that solve my naming issues.

Then you have to change all references to that private attribute. What's
the problem here? As it was private I would expect to find all the
references "nearby" in the same module or class.

Right, but tmp isn't private.
>>>>And in python the reverse can be true :

The reverse is hardly ever true. 90% of public APIs in almost all
languages are methods or functions.

Except the ones with properties where ordinary "attributes" may be just
calls in disguise.


Crap! Even in Python too most Public APIs are methods and functions.

>>Python is not almost all other languages and in Python code you usually
won't find those trivial getters and setters because we have properties if
the access might become a bit more complex in the future.


Ha! I bet you haven't read too many Python codes.

One thing I can more or less guarantee is that if you'd invested the
time you've spent on this thread in actually performing whatever trivial
but tedious engineering work was required to achieve the renaming of
that attribute the job would have been completed long ago.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Jul 14 '06 #55

mystilleef ha scritto:
Methods are used to perform actions. Data attributes usually aren't. We
are on different planes.
You aren't thinking pythonic. You should not make any difference
between accessing an attribute and accessing a function. They both just
need to receive the right data to process (and the module doc must tell
you wich is it).
There is of course many python code wich doesn't use properties, but
that's up to the developer: everybody write the way they like. You
could also find code with both getter/setter AND properties.
well used properties make your code cleaner, but if you don't find
yourself confortable with them, just don't use them, but never forget
them.

Riccardo

Jul 14 '06 #56
On State and Behavior:

To understand objects in terms of state and behavior you need to
absolve yourself from implementation details of languages and think at
an abstract level.

Take a button object, for example. It has state and behavior. Possible
states may include, is_active, is_focused, is_mapped, etc. Behavior is
what the button does when it responds to events, (e.g when you click on
it, or drag it, or position a pointer over it.) If you've done any form
of event based programming (GUI/Games/Simulation), this method of
thinking becomes natural.

As you can see, when I'm designing a button object, I don't care what
Python does with is_active. I don't care how it accesses. I don't care
what is_active means to Python. I don't care about Python's __get__
/__set__ special/latent functions or implementation details. is_active
to me and every other developer is a state of the button object. And at
that level that's all that matters. Python can tell me it's just ones
and zeros for all I care.

In very well designed systems, the state of an object should only be
changed by the object. For example, a third party randomly changing
is_active, (which Python lets you do freely and easily) from False to
True may crash your GUI. And I'm not making this up. Things like this
do really happen depending on the whackyness of your toolkit. So
sometimes, it is my duty to protect the state of an object. Especially
if its state cannot afford to be corrupted rendering the system
unstable. And situations like this are found a plenty in event based
programming. Which is programming objects based almost entirely on
state and behavior. As you can see this has nothing to do with Python
vs Java's vs X's implementation of accessors and how using them sucks,
or how they aren't Pythonic. Some domains just require this stuff.

One of the requirements for designing robust object systems is ensuring
the state of objects aren't easily contaminated. That "state" is the
objects data (read: stuff the object needs to do something "reliably").
And this is why many overzealous OO languages do "force" you to use
accessors. It's not because they hate you or aren't aware of the
convenience of having direct access to an object's attributes. It's
just because these languages convenience/robustness ratios are
different.

Thinking in terms of callable vs non-callable is not helpful for me,
because it isn't high level enough. Thinking in terms of state and
behavior is, because it works regardless of programming language or
implementations. This is the reason I like working with Python. I
wanted a language that didn't bore me with it semantics and allowed me
to focus on design. Let me reiterate, I'm not obsessing over language
semantics, I just need practical, not religious, solutions for my
problem domain.

Bruno Desthuilliers wrote:
mystilleef wrote:
(snip)

Okay, I feel I need to make myself clear. I certainly I'm not blaming
Python for my mistakes. And I don't think language X is better than
Python or vice-versa. Okay scrap the vice-versa. It was silly of me to
name the variable tmp regardless of whatever excuses I have. This also
doesn't mean in the future I wouldn't use shitty names for my
attributes. :-) I most likely will. But at least now I know how to
minimize its impact of such carelessness. I mentioned them above but I
repeat it hear again.

1). Make all attributes of a class private/protected .

Please re-read my answer to your previous mention of this and my other
remarks in this thread (and below in this thread) about the profound
differences between Python and Java wrt/ object model and attribute
access semantics.
2). If a "non-callable" attribute is going to be used outside a class,
think about making it a property

Unless you don't need to.
and name the property well,

Indeed !-)
Other than that we are just arguing semantics of language. For example,
your view of objects is by categorizing its attributes in callable and
non-callable.

And also API/implementation. These are to orthogonal problems - even in
Java FWIW !-)
However, my categorization is state(data) and
behavior(methods).

If properties are an equivalent of getters/setters, are properties state
or behaviour ? According to your views, they are behaviour, if I
understood you. In that case, what's the difference between 'directely'
(which in fact implies going thru __getattribute__) accessing a public
"data" attribute and accessing an implementation attribute by the mean
of a descriptor (property or custom) ?

* before:

# mylib.py
class Knight(object):
def __init__(self, name):
self.name = name

def sayHello(self):
print "hello, I'm %s" % self.name

# mymain.py
from mylib import Knight
k = Knight("Robin")
print k.name
k.sayHello()
k.name = "Lancelot"
k.sayHello()

* after
# mylib.py
class Knight(object):
def __init__(self, name):
self.name = name

@apply
def name():
def fget(self):
return self._xxx.capitalize()

def fset(self, name):
self._xxx = name

def sayHello(self):
print "hello, I'm %s" % self.name

# mymain.py
from mylib import Knight
k = Knight("Robin")
print k.name
k.sayHello()
k.name = "Lancelot"
k.sayHello()
Neither ways of thinking about it is wrong.

From the client code (including other methods of the same class) POV, is
Knight.name behaviour or state ? Please, don't see it as a flame or a
pissing context or whatever, and try to seriously answer this question.

Thinking in terms of state and behaviour is certainly not wrong in
itself, but what is state and what is behaviour ? If I pass a callable
as an argument to another callable, is the first one data or behaviour ?
If I return a callable from a another callable, is the first callable
data or behaviour ? In a Partial application object [1], is the stored
callable data or behaviour ? Is the class of an object data or
behaviour? Is it's metaclass data or behaviour ?

[1] http://www.python.org/dev/peps/pep-0309/

It just
reflects the way we design classes. When I'm coding I certainly don't
care about how Python accesses tmp.

Neither do I. But I have in mind how I can change the way it is accessed.
What I do care about is how to
change tmp without breaking code left, right and center and the
facilities Python provides for making my code robust.

cf Simon's answer and mines. But your original problem is not related to
tmp being callable or not, it's related to how you use to think about
them, hence name them.
Most other OO
languages provide accessors in addition to keywords for that kind of
stuff.

Most OO languages *don't* provide you accessors - they indeed *forces
you* to write them even for the most trivial cases. What Python (or any
other language supporting "computed attributes" syntax) gives you is a
way to avoid writing tedious, boilerplate code. Not more, not less.
I knew it wasn't Pythonic, but I wanted to know the Pythonic way
to do it. So I asked. My query does not automatically suggest Python
sucks. Neither those it suggest that Java or other OO languages are
better. I asked because I sincerely wanted to know the Pythonic way
handling issues like that.

Mark as implementation what is obviously implementation (be it callable
or not), mark as API what is obviously API (be it callable or not). In
both cases, there will be simple ways to either expose an implementation
name or make a non-callable attribute a property. And *always* try to be
careful about naming, at least (but not restricted to) wrt/ your API.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 15 '06 #57
On 2006-07-15 06:55:14, mystilleef wrote:
In very well designed systems, the state of an object should only be
changed by the object.
IMO that's not quite true. Ultimately, the state always gets changed by
something else (user interaction, physical events); very few objects are
completely self-contained in their behavior.

In most systems (and you possibly have written some of them) are objects
whose state gets changed by other objects -- possibly through the
intermediation of setter methods that do nothing else but set the state.
There's no conceptual difference between directly setting the state or
calling a setter function that does nothing else but directly setting the
state -- except for one unnecessary level of indirection in the latter.
For example, a third party randomly changing is_active, (which Python
lets you do freely and easily) from False to True may crash your GUI.
And I'm not making this up. Things like this do really happen depending
on the whackyness of your toolkit.
That's quite true, but a setter that does nothing but change is_active
doesn't prevent this. If there is logic necessary to prevent state changes
in certain situations, this should be implemented. But whether you then
call this a part of the "behavior" (looking at the implementation as being
a setter method) or a part of the "state" (looking at the implementation as
being an added feature of the attribute) doesn't really make an objective
difference.
So sometimes, it is my duty to protect the state of an object.
Of course.
Which is programming objects based almost entirely on state and behavior.
As you can see this has nothing to do with Python vs Java's vs X's
implementation of accessors and how using them sucks, or how they aren't
Pythonic. Some domains just require this stuff.
Yes, but you seem to still be stuck in the paradigm that setting the state
is behavior if it comes from the outside -- probably because some languages
implement that way.

I'm not (yet) a Python programmer. To be honest, the one single feature
that attracted me to Python is the structuring by indenting... I never
understood why we have to indent (to be able to read) /and/ brace (to make
the compiler happy) in other languages -- I always thought that if
indenting helps me to understand the structure, the compiler should be able
to read exactly that :)

I come from a mostly C/C++/Java/PHP background, apparently similar to
yours. GUI, embedded, whatever. But I can understand that the difference
you are making is not based in a concept, it is based in an implementation.

It is an artificial difference to say that

o.is_active = true

is modifying state, whereas

o.set_active( true )

is dealing with behavior. Either way you are changing the state. Behavior,
that is, doing something, implies state change, one way or another,
sometimes relevant, sometimes not. There are (often embedded) systems, and
well-designed ones, that basically don't deal with what you call behavior
at all and handle everything through state change (of signals). Such
systems can be rock-solid and quite complex, and have a lot of "behavior".
And there are systems that do everything through what you call behavior
(e.g. getter/setter type implementations). Both types can work, both can
achieve the exactly same; this is just an implementation detail.
And this is why many overzealous OO languages do "force" you to use
accessors.
I'm not sure why you keep on harping on this. It seems to have been clearly
stated that in Python, every attribute /is/ an implied getter/setter pair
-- it's up to you to just let the language use the default (simple)
implementation, or override it with your own logic. It is also up to you to
call this added logic then a feature of "behavior" or of "state".
Thinking in terms of state and behavior is, because it works regardless
of programming language or implementations.
Agreed. But the distinction is not universal, objective, it is subjective.
Where you make it is your choice. As the examples above show, there are
well-working solid systems out there that work on both ends of your
spectrum: only behavior is exposed, or only state is exposed. Both can
achieve the same. It is a subjective choice to call this

o.is_active = true

state or behavior... the underlying setter implementation for is_active can
do everything you want your behavior to be -- or it can be the simple
straightforward default setter. It's just a subjective thing to say that
this is in the realm of behavior or of state. Didn't you say that state
changes can crash a system? That's behavior, as far as I am concerned :)
And there is little if any behavior that doesn't change the state --
especially setters are known to do that :)

Gerhard

Jul 15 '06 #58

Gerhard Fiedler wrote:
On 2006-07-15 06:55:14, mystilleef wrote:
In very well designed systems, the state of an object should only be
changed by the object.

IMO that's not quite true. Ultimately, the state always gets changed by
something else (user interaction, physical events); very few objects are
completely self-contained in their behavior.
Then in those cases the system becomes a victim of high coupling.
In most systems (and you possibly have written some of them) are objects
whose state gets changed by other objects -- possibly through the
intermediation of setter methods that do nothing else but set the state.
There's no conceptual difference between directly setting the state or
calling a setter function that does nothing else but directly setting the
state -- except for one unnecessary level of indirection in the latter.
It depends. If certain conditions need to be met before changing the
state of an object, then arbitrarily changing it can be dangerous. I
gave an example earlier.
For example, a third party randomly changing is_active, (which Python
lets you do freely and easily) from False to True may crash your GUI.
And I'm not making this up. Things like this do really happen depending
on the whackyness of your toolkit.

That's quite true, but a setter that does nothing but change is_active
doesn't prevent this. If there is logic necessary to prevent state changes
in certain situations, this should be implemented. But whether you then
call this a part of the "behavior" (looking at the implementation as being
a setter method) or a part of the "state" (looking at the implementation as
being an added feature of the attribute) doesn't really make an objective
difference.
Of course using setters for the sake of just using them is pointless.
The reason to use them is if pre-conditions or post-conditions need to
be met. Or to control access to an objects states.
So sometimes, it is my duty to protect the state of an object.

Of course.
Which is programming objects based almost entirely on state and behavior.
As you can see this has nothing to do with Python vs Java's vs X's
implementation of accessors and how using them sucks, or how they aren't
Pythonic. Some domains just require this stuff.

Yes, but you seem to still be stuck in the paradigm that setting the state
is behavior if it comes from the outside -- probably because some languages
implement that way.
Not at all. Behaviors are just methods of an object. They are behaviors
whether they are called internally or externally.
I'm not (yet) a Python programmer. To be honest, the one single feature
that attracted me to Python is the structuring by indenting... I never
understood why we have to indent (to be able to read) /and/ brace (to make
the compiler happy) in other languages -- I always thought that if
indenting helps me to understand the structure, the compiler should be able
to read exactly that :)

I come from a mostly C/C++/Java/PHP background, apparently similar to
yours. GUI, embedded, whatever. But I can understand that the difference
you are making is not based in a concept, it is based in an implementation.

It is an artificial difference to say that

o.is_active = true

is modifying state, whereas

o.set_active( true )

is dealing with behavior. Either way you are changing the state. Behavior,
that is, doing something, implies state change, one way or another,
sometimes relevant, sometimes not. There are (often embedded) systems, and
well-designed ones, that basically don't deal with what you call behavior
at all and handle everything through state change (of signals). Such
systems can be rock-solid and quite complex, and have a lot of "behavior".
And there are systems that do everything through what you call behavior
(e.g. getter/setter type implementations). Both types can work, both can
achieve the exactly same; this is just an implementation detail.
If all set_active does is change is_active's state, then set_active is
pointless. See above for my point on the issue.
And this is why many overzealous OO languages do "force" you to use
accessors.

I'm not sure why you keep on harping on this. It seems to have been clearly
stated that in Python, every attribute /is/ an implied getter/setter pair
-- it's up to you to just let the language use the default (simple)
implementation, or override it with your own logic. It is also up to you to
call this added logic then a feature of "behavior" or of "state".
Thinking in terms of state and behavior is, because it works regardless
of programming language or implementations.

Agreed. But the distinction is not universal, objective, it is subjective.
Where you make it is your choice. As the examples above show, there are
well-working solid systems out there that work on both ends of your
spectrum: only behavior is exposed, or only state is exposed. Both can
achieve the same. It is a subjective choice to call this

o.is_active = true

state or behavior... the underlying setter implementation for is_active can
do everything you want your behavior to be -- or it can be the simple
straightforward default setter. It's just a subjective thing to say that
this is in the realm of behavior or of state. Didn't you say that state
changes can crash a system? That's behavior, as far as I am concerned :)
And there is little if any behavior that doesn't change the state --
especially setters are known to do that :)

Gerhard
State - behavior is not something I made up, so it isn't subjective. It
is a common term used in OO literature. In fact, the only reason I used
it is because I thought is was common knowledge. And behaviors are not
just necessarily getters/setters, they are methods of objects.

Jul 15 '06 #59
On 2006-07-15 12:04:20, mystilleef wrote:
State - behavior is not something I made up, so it isn't subjective. It
is a common term used in OO literature. In fact, the only reason I used
it is because I thought is was common knowledge.
Of course. But your association of state with attributes and behavior with
methods is arbitrary to a specific implementation. Of course you probably
will have always something like attributes to store state, but you may
trigger behavior just as well through state changes as you may trigger it
through method calls or other means. (Remember, this is about the public
API, not about implementation details.)

Gerhard

Jul 15 '06 #60
On 2006-07-15, Gerhard Fiedler <ge*****@gmail.comwrote:
On 2006-07-15 06:55:14, mystilleef wrote:
>In very well designed systems, the state of an object should only be
changed by the object.

IMO that's not quite true. Ultimately, the state always gets changed by
something else (user interaction, physical events); very few objects are
completely self-contained in their behavior.

In most systems (and you possibly have written some of them) are objects
whose state gets changed by other objects -- possibly through the
intermediation of setter methods that do nothing else but set the state.
There's no conceptual difference between directly setting the state or
calling a setter function that does nothing else but directly setting the
state -- except for one unnecessary level of indirection in the latter.
The conceptual difference is that a function call is more like an "event",
a variable is more like a "process".

An object that provides a setter is a process that is prepared to engage
in this "set event". An object that exposes a variable is a process that
interacts with this variable which the user is also invited to interact
with concurrently.

So with a setter in the API, conceptually, there are two processes
sharing the set event: the object itself, and the process that's calling
the setter. With an exposed variable, there are three: the object, the
variable in between, and the calling process.

Restricting yourself to setters and getters is a bit like saying we
build a machine that only has touch-keys and lights on the outside.
Shared variables are more like a machine with levers and dials you set,
and bits that pop up, like the numbers on mechanical cash-registers.
They have "state" on the outside, not just on the inside. Such designs
can be less tolerant of unsympathetic input-- think how easy it is to
jam up an old-fashioned typewriter if you just press a few keys at the
same time.

There isn't any practical difference, as you say, if all the setter does
is set. But it might easily do a few other subtle things, in particular
wait for a good moment to actually effect the change.
Jul 15 '06 #61
On 2006-07-15 19:46:16, Ben C wrote:
There isn't any practical difference, as you say, if all the setter does
is set. But it might easily do a few other subtle things, in particular
wait for a good moment to actually effect the change.
I agree. But even then, for me there's no practical difference between
calling a setter that does those other subtle things, or setting an
attribute, and by this triggering the associated property handler than then
does what in the other case the setter would do.

Gerhard

Jul 16 '06 #62
mystilleef wrote:
<ot>Please don't top-post</ot>
On State and Behavior:

To understand objects in terms of state and behavior you need to
absolve yourself from implementation details of languages
and think at an abstract level.

Take a button object, for example. It has state and behavior. Possible
states may include, is_active, is_focused, is_mapped, etc. Behavior is
what the button does when it responds to events, (e.g when you click on
it, or drag it, or position a pointer over it.) If you've done any form
of event based programming (GUI/Games/Simulation), this method of
thinking becomes natural.

As you can see, when I'm designing a button object, I don't care what
Python does with is_active. I don't care how it accesses. I don't care
what is_active means to Python. I don't care about Python's __get__
/__set__ special/latent functions or implementation details. is_active
to me and every other developer is a state of the button object. And at
that level that's all that matters. Python can tell me it's just ones
and zeros for all I care.

In very well designed systems, the state of an object should only be
changed by the object.
.... as a response to a message.
For example, a third party randomly changing
is_active, (which Python lets you do freely and easily)
Unless you make it a read-only property.
from False to
True may crash your GUI.
And I'm not making this up. Things like this
do really happen depending on the whackyness of your toolkit. So
sometimes, it is my duty to protect the state of an object. Especially
if its state cannot afford to be corrupted rendering the system
unstable. And situations like this are found a plenty in event based
programming. Which is programming objects based almost entirely on
state and behavior. As you can see this has nothing to do with Python
vs Java's vs X's implementation of accessors and how using them sucks,
or how they aren't Pythonic. Some domains just require this stuff.
Properties *are* 'accessors'.
One of the requirements for designing robust object systems is ensuring
the state of objects aren't easily contaminated.
"contaminated" ???
That "state" is the
objects data (read: stuff the object needs to do something "reliably").
Makes no sens to me.
And this is why many overzealous OO languages do "force" you to use
accessors. It's not because they hate you or aren't aware of the
convenience of having direct access to an object's attributes. It's
just because these languages convenience/robustness ratios are
different.

Thinking in terms of callable vs non-callable is not helpful for me,
because it isn't high level enough.
Allo, Huston ?
Thinking in terms of state and
behavior is, because it works regardless of programming language or
implementations. This is the reason I like working with Python. I
wanted a language that didn't bore me with it semantics and allowed me
to focus on design. Let me reiterate, I'm not obsessing over language
semantics, I just need practical, not religious, solutions for my
problem domain.
Using properties instead of explicit getters/setters is pragmatism, not
religion. Using the default get/set mechanism when there's no specific
reason to do otherwise is pragmatism too. And understanding the object
model and idioms of the language you're using is IMHO the very pragmatic
thing to do...

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 17 '06 #63
mystilleef wrote:
Gerhard Fiedler wrote:
>>On 2006-07-15 06:55:14, mystilleef wrote:

>>>In very well designed systems, the state of an object should only be
changed by the object.

IMO that's not quite true. Ultimately, the state always gets changed by
something else (user interaction, physical events); very few objects are
completely self-contained in their behavior.
Then in those cases the system becomes a victim of high coupling.
Time to burn your book and face reality. ObjA sends message Msg1 to
ObjB. Part of the associated behaviour is that in responce to Msg1, objB
changes it's own state. Practical result : ObjB's state has been changed
by ObjA. Practical question : how do you hope to avoid this "hi
coupling" (lol), apart from making all your objects totally autistic ?
>>In most systems (and you possibly have written some of them) are objects
whose state gets changed by other objects -- possibly through the
intermediation of setter methods that do nothing else but set the state.
There's no conceptual difference between directly setting the state or
calling a setter function that does nothing else but directly setting the
state -- except for one unnecessary level of indirection in the latter.


It depends. If certain conditions need to be met before changing the
state of an object, then arbitrarily changing it can be dangerous.
Does this imply a 'method call' *syntax* ? Given the existence of
"computed attributes" (ie: support for 'attribute access' *syntax* with
hidden accessors) and the possibility to redefine implementation (from
default attribute r/w access to computed/controlled) without touching
the interface, why advocate the *systematic* use of computed attributes
when it's just duplicating the default behaviour ?

>
>>>For example, a third party randomly changing is_active, (which Python
lets you do freely and easily) from False to True may crash your GUI.
And I'm not making this up. Things like this do really happen depending
on the whackyness of your toolkit.

That's quite true, but a setter that does nothing but change is_active
doesn't prevent this. If there is logic necessary to prevent state changes
in certain situations, this should be implemented. But whether you then
call this a part of the "behavior" (looking at the implementation as being
a setter method) or a part of the "state" (looking at the implementation as
being an added feature of the attribute) doesn't really make an objective
difference.


Of course using setters for the sake of just using them is pointless.
Indeed.
The reason to use them is if pre-conditions or post-conditions need to
be met. Or to control access to an objects states.
Then why advocate *systematic* use of them ?

(snip)
>
State - behavior is not something I made up, so it isn't subjective.
The words (and the concept they describe) are not. Interpretation of
what is state and what is behaviour is subjective.
It
is a common term used in OO literature. In fact, the only reason I used
it is because I thought is was common knowledge.
It is.
And behaviors are not
just necessarily getters/setters, they are methods of objects.
Behaviour is how a given object reacts to a given message. *Nothing* in
this implies the notions of attributes or methods. Attributes and
methods are implementation details of the concepts of state and
behaviour, and - while this is a common implementation of OO concepts -
the choice to use non-callable attributes as representing the state
and callable ones as representing behaviour is totally
implementation-dependant.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 17 '06 #64
Bruno Desthuilliers wrote:
mystilleef wrote:
(snip)
>>Here are the lessons I've learned (the hard way).

1) Make all attributes of a class private or protected.


Unless they are obviously part of the implementation
s/implementation/interface/, of course.
(ie: when you would
definitively had written getters/setters in Java), in which case make
them public (and name them with the same care you would have for Java
getters/setters). You can change the implementation later.
(snip)

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 17 '06 #65

Bruno Desthuilliers wrote:
mystilleef wrote:
<ot>Please don't top-post</ot>
On State and Behavior:

To understand objects in terms of state and behavior you need to
absolve yourself from implementation details of languages
and think at an abstract level.


Take a button object, for example. It has state and behavior. Possible
states may include, is_active, is_focused, is_mapped, etc. Behavior is
what the button does when it responds to events, (e.g when you click on
it, or drag it, or position a pointer over it.) If you've done any form
of event based programming (GUI/Games/Simulation), this method of
thinking becomes natural.

As you can see, when I'm designing a button object, I don't care what
Python does with is_active. I don't care how it accesses. I don't care
what is_active means to Python. I don't care about Python's __get__
/__set__ special/latent functions or implementation details. is_active
to me and every other developer is a state of the button object. And at
that level that's all that matters. Python can tell me it's just ones
and zeros for all I care.

In very well designed systems, the state of an object should only be
changed by the object.

... as a response to a message.
For example, a third party randomly changing
is_active, (which Python lets you do freely and easily)

Unless you make it a read-only property.
So you see the purpose of accessors then?
from False to
True may crash your GUI.
And I'm not making this up. Things like this
do really happen depending on the whackyness of your toolkit. So
sometimes, it is my duty to protect the state of an object. Especially
if its state cannot afford to be corrupted rendering the system
unstable. And situations like this are found a plenty in event based
programming. Which is programming objects based almost entirely on
state and behavior. As you can see this has nothing to do with Python
vs Java's vs X's implementation of accessors and how using them sucks,
or how they aren't Pythonic. Some domains just require this stuff.

Properties *are* 'accessors'.
I never said they weren't.
One of the requirements for designing robust object systems is ensuring
the state of objects aren't easily contaminated.

"contaminated" ???
Make an object's state unreliable. See above example.
That "state" is the
objects data (read: stuff the object needs to do something "reliably").

Makes no sens to me.
is_active is an object's data, with regards to our example.
And this is why many overzealous OO languages do "force" you to use
accessors. It's not because they hate you or aren't aware of the
convenience of having direct access to an object's attributes. It's
just because these languages convenience/robustness ratios are
different.

Thinking in terms of callable vs non-callable is not helpful for me,
because it isn't high level enough.

Allo, Huston ?
Thinking in terms of state and
behavior is, because it works regardless of programming language or
implementations. This is the reason I like working with Python. I
wanted a language that didn't bore me with it semantics and allowed me
to focus on design. Let me reiterate, I'm not obsessing over language
semantics, I just need practical, not religious, solutions for my
problem domain.

Using properties instead of explicit getters/setters is pragmatism, not
religion. Using the default get/set mechanism when there's no specific
reason to do otherwise is pragmatism too. And understanding the object
model and idioms of the language you're using is IMHO the very pragmatic
thing to do...
Again, the object model of the language is irrelevant. The only
relevant model is my application's model, which should work regardless
of the language I use.

Jul 18 '06 #66

Bruno Desthuilliers wrote:
mystilleef wrote:
Gerhard Fiedler wrote:
>On 2006-07-15 06:55:14, mystilleef wrote:
In very well designed systems, the state of an object should only be
changed by the object.

IMO that's not quite true. Ultimately, the state always gets changed by
something else (user interaction, physical events); very few objects are
completely self-contained in their behavior.
Then in those cases the system becomes a victim of high coupling.

Time to burn your book and face reality. ObjA sends message Msg1 to
ObjB. Part of the associated behaviour is that in responce to Msg1, objB
changes it's own state. Practical result : ObjB's state has been changed
by ObjA. Practical question : how do you hope to avoid this "hi
coupling" (lol), apart from making all your objects totally autistic ?
Are you serious? Well, you design an object that serves as a mediator.
All objects can then only interact with themselves and the mediator
only. Via signals, objects learn to automatically adjust their states
and respond to events. This is just one of several methods you can
dramatically reduce coupling. I'm sure glad I didn't burn my book.
>In most systems (and you possibly have written some of them) are objects
whose state gets changed by other objects -- possibly through the
intermediation of setter methods that do nothing else but set the state.
There's no conceptual difference between directly setting the state or
calling a setter function that does nothing else but directly setting the
state -- except for one unnecessary level of indirection in the latter.

It depends. If certain conditions need to be met before changing the
state of an object, then arbitrarily changing it can be dangerous.

Does this imply a 'method call' *syntax* ?
That's language dependent.
>Given the existence of
"computed attributes" (ie: support for 'attribute access' *syntax* with
hidden accessors) and the possibility to redefine implementation (from
default attribute r/w access to computed/controlled) without touching
the interface, why advocate the *systematic* use of computed attributes
when it's just duplicating the default behaviour ?
I'm not advocating anything. I'm just stating the use case for
accessors and the wisdom behind them. My qualm with implicit accessors
remains the name issue.
>
>>For example, a third party randomly changing is_active, (which Python
lets you do freely and easily) from False to True may crash your GUI.
And I'm not making this up. Things like this do really happen depending
on the whackyness of your toolkit.

That's quite true, but a setter that does nothing but change is_active
doesn't prevent this. If there is logic necessary to prevent state changes
in certain situations, this should be implemented. But whether you then
call this a part of the "behavior" (looking at the implementation as being
a setter method) or a part of the "state" (looking at the implementation as
being an added feature of the attribute) doesn't really make an objective
difference.

Of course using setters for the sake of just using them is pointless.

Indeed.
The reason to use them is if pre-conditions or post-conditions need to
be met. Or to control access to an objects states.

Then why advocate *systematic* use of them ?

(snip)
I never advocated anything. On the contrary, I asked a query?

State - behavior is not something I made up, so it isn't subjective.

The words (and the concept they describe) are not. Interpretation of
what is state and what is behaviour is subjective.
It
is a common term used in OO literature. In fact, the only reason I used
it is because I thought is was common knowledge.

It is.
And behaviors are not
just necessarily getters/setters, they are methods of objects.

Behaviour is how a given object reacts to a given message. *Nothing* in
this implies the notions of attributes or methods. Attributes and
methods are implementation details of the concepts of state and
behaviour, and - while this is a common implementation of OO concepts -
the choice to use non-callable attributes as representing the state
and callable ones as representing behaviour is totally
implementation-dependant.
I agree. And I already told you I think in terms of state and behavior
and not language dependent semantics.

Jul 18 '06 #67
mystilleef wrote:
Bruno Desthuilliers wrote:
>>mystilleef wrote:
>>>Gerhard Fiedler wrote:
On 2006-07-15 06:55:14, mystilleef wrote:

>In very well designed systems, the state of an object should only be
>changed by the object.

IMO that's not quite true. Ultimately, the state always gets changed by
something else (user interaction, physical events); very few objects are
completely self-contained in their behavior.
Then in those cases the system becomes a victim of high coupling.

Time to burn your book and face reality. ObjA sends message Msg1 to
ObjB. Part of the associated behaviour is that in responce to Msg1, objB
changes it's own state. Practical result : ObjB's state has been changed
by ObjA. Practical question : how do you hope to avoid this "hi
coupling" (lol), apart from making all your objects totally autistic ?


Are you serious?
Deadly serious. But I'm afraid you're still missing the point.
Well, you design an object that serves as a mediator.
All objects can then only interact with themselves and the mediator
only. Via signals, objects learn to automatically adjust their states
and respond to events.
signal -message -method call -change state.

Spell it how you like, add as many indirection levels you want, it still
boils down to the fact that *something* triggers the state change.
This is just one of several methods you can
dramatically reduce coupling.
It's just one of several methods that dramatically increases complexity,
without changing anything to the fact that in the end, *practically*,
some object ObjA changes its state as a response to a message sent by ObjB.
I'm sure glad I didn't burn my book.
No comment.
>
>>>>In most systems (and you possibly have written some of them) are objects
whose state gets changed by other objects -- possibly through the
intermediation of setter methods that do nothing else but set the state.
There's no conceptual difference between directly setting the state or
calling a setter function that does nothing else but directly setting the
state -- except for one unnecessary level of indirection in the latter.

It depends. If certain conditions need to be met before changing the
state of an object, then arbitrarily changing it can be dangerous.

Does this imply a 'method call' *syntax* ?


That's language dependent.

>>Given the existence of
"computed attributes" (ie: support for 'attribute access' *syntax* with
hidden accessors) and the possibility to redefine implementation (from
default attribute r/w access to computed/controlled) without touching
the interface, why advocate the *systematic* use of computed attributes
when it's just duplicating the default behaviour ?


I'm not advocating anything.
cf below on this.
I'm just stating the use case for
accessors and the wisdom behind them. My qualm with implicit accessors
remains the name issue.
The "name issue" is *your* problem. And AFAICT, it's a "problem" because
you refuse to free your mind from a "what's in the book" mindset.
>
>>>>>For example, a third party randomly changing is_active, (which Python
>lets you do freely and easily) from False to True may crash your GUI.
>And I'm not making this up. Things like this do really happen depending
>on the whackyness of your toolkit.

That's quite true, but a setter that does nothing but change is_active
doesn't prevent this. If there is logic necessary to prevent state changes
in certain situations, this should be implemented. But whether you then
call this a part of the "behavior" (looking at the implementation as being
a setter method) or a part of the "state" (looking at the implementation as
being an added feature of the attribute) doesn't really make an objective
difference.

Of course using setters for the sake of just using them is pointless.

Indeed.

>>>The reason to use them is if pre-conditions or post-conditions need to
be met. Or to control access to an objects states.

Then why advocate *systematic* use of them ?

(snip)

I never advocated anything.
You advocated
"""
1). Make all attributes of a class private/protected .
2). If a "non-callable" attribute is going to be used outside a class,
think about making it a property and name the property well, because
you never know...
"""
>
>>>State - behavior is not something I made up, so it isn't subjective.

The words (and the concept they describe) are not. Interpretation of
what is state and what is behaviour is subjective.

>>>It
is a common term used in OO literature. In fact, the only reason I used
it is because I thought is was common knowledge.

It is.

>>>And behaviors are not
just necessarily getters/setters, they are methods of objects.

Behaviour is how a given object reacts to a given message. *Nothing* in
this implies the notions of attributes or methods. Attributes and
methods are implementation details of the concepts of state and
behaviour, and - while this is a common implementation of OO concepts -
the choice to use non-callable attributes as representing the state
and callable ones as representing behaviour is totally
implementation-dependant.

I agree. And I already told you I think in terms of state and behavior
and not language dependent semantics.
Then why do you advise "(making) all attributes of a class
private/protected" and systematically using properties ?

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 18 '06 #68
mystilleef wrote:
Bruno Desthuilliers wrote:
>>mystilleef wrote:
<ot>Please don't top-post</ot>
>>>On State and Behavior:

To understand objects in terms of state and behavior you need to
absolve yourself from implementation details of languages
and think at an abstract level.


>>>Take a button object, for example. It has state and behavior. Possible
states may include, is_active, is_focused, is_mapped, etc. Behavior is
what the button does when it responds to events, (e.g when you click on
it, or drag it, or position a pointer over it.) If you've done any form
of event based programming (GUI/Games/Simulation), this method of
thinking becomes natural.

As you can see, when I'm designing a button object, I don't care what
Python does with is_active. I don't care how it accesses. I don't care
what is_active means to Python. I don't care about Python's __get__
/__set__ special/latent functions or implementation details. is_active
to me and every other developer is a state of the button object. And at
that level that's all that matters. Python can tell me it's just ones
and zeros for all I care.

In very well designed systems, the state of an object should only be
changed by the object.

... as a response to a message.

>>>For example, a third party randomly changing
is_active, (which Python lets you do freely and easily)

Unless you make it a read-only property.

So you see the purpose of accessors then?
*where* did I say *anything* that could *possibly* be taken as me not
seeing the point of computed attributes ?

What I'm saying here is that it's totally useless to duplicate default
behaviour.
>
>>>from False to
True may crash your GUI.
>>>And I'm not making this up. Things like this
do really happen depending on the whackyness of your toolkit. So
sometimes, it is my duty to protect the state of an object. Especially
if its state cannot afford to be corrupted rendering the system
unstable. And situations like this are found a plenty in event based
programming. Which is programming objects based almost entirely on
state and behavior. As you can see this has nothing to do with Python
vs Java's vs X's implementation of accessors and how using them sucks,
or how they aren't Pythonic. Some domains just require this stuff.

Properties *are* 'accessors'.

I never said they weren't.
Fine.

Now : in a language with support for computed attributes, direct
attribute access is the default r/w accessors.
>
>>>One of the requirements for designing robust object systems is ensuring
the state of objects aren't easily contaminated.

"contaminated" ???
Make an object's state unreliable. See above example.
That's the word you choose that I find really strange.
>
>>>That "state" is the
objects data (read: stuff the object needs to do something "reliably").

Makes no sens to me.

is_active is an object's data,
class Obj(object):
# ....
@apply
def is_active():
def fget(self):
return (self.something and self.computeThis()) \
or self.otherCondition()
def fset(self, val):
raise ReadOnlyError()
def fdel(self):
raise UndeletableError()
return **locals()

According to *your* sayings, Obj.is_active is "behaviour"...
>>>And this is why many overzealous OO languages do "force" you to use
accessors.
The only languages I know that "force" you to use accessors are
Smalltalk and Ruby (and Ruby offers some syntactic sugar for 'default' -
ie r/w - accessors).
It's not because they hate you or aren't aware of the
>>>convenience of having direct access to an object's attributes. It's
just because these languages convenience/robustness ratios are
different.
I'm afraid it has very few to do with "robustness".
>>>Thinking in terms of callable vs non-callable is not helpful for me,
because it isn't high level enough.

Allo, Huston ?

>>>Thinking in terms of state and
behavior is, because it works regardless of programming language or
implementations. This is the reason I like working with Python. I
wanted a language that didn't bore me with it semantics and allowed me
to focus on design. Let me reiterate, I'm not obsessing over language
semantics, I just need practical, not religious, solutions for my
problem domain.

Using properties instead of explicit getters/setters is pragmatism, not
religion. Using the default get/set mechanism when there's no specific
reason to do otherwise is pragmatism too. And understanding the object
model and idioms of the language you're using is IMHO the very pragmatic
thing to do...

Again, the object model of the language is irrelevant.
Allo, Huston ?
The only
relevant model is my application's model, which should work regardless
of the language I use.
What to say...

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 18 '06 #69

Bruno Desthuilliers wrote:
mystilleef wrote:
Bruno Desthuilliers wrote:
>mystilleef wrote:

Gerhard Fiedler wrote:
On 2006-07-15 06:55:14, mystilleef wrote:

In very well designed systems, the state of an object should only be
changed by the object.

IMO that's not quite true. Ultimately, the state always gets changed by
something else (user interaction, physical events); very few objects are
completely self-contained in their behavior.
Then in those cases the system becomes a victim of high coupling.

Time to burn your book and face reality. ObjA sends message Msg1 to
ObjB. Part of the associated behaviour is that in responce to Msg1, objB
changes it's own state. Practical result : ObjB's state has been changed
by ObjA. Practical question : how do you hope to avoid this "hi
coupling" (lol), apart from making all your objects totally autistic ?

Are you serious?

Deadly serious. But I'm afraid you're still missing the point.
Well, you design an object that serves as a mediator.
All objects can then only interact with themselves and the mediator
only. Via signals, objects learn to automatically adjust their states
and respond to events.

signal -message -method call -change state.

Spell it how you like, add as many indirection levels you want, it still
boils down to the fact that *something* triggers the state change.
Riiiiight!
This is just one of several methods you can
dramatically reduce coupling.

It's just one of several methods that dramatically increases complexity,
without changing anything to the fact that in the end, *practically*,
some object ObjA changes its state as a response to a message sent by ObjB.
Say that to game/simulation developers.
I'm sure glad I didn't burn my book.

No comment.
>>>In most systems (and you possibly have written some of them) are objects
whose state gets changed by other objects -- possibly through the
intermediation of setter methods that do nothing else but set the state.
There's no conceptual difference between directly setting the state or
calling a setter function that does nothing else but directly setting the
state -- except for one unnecessary level of indirection in the latter.

It depends. If certain conditions need to be met before changing the
state of an object, then arbitrarily changing it can be dangerous.

Does this imply a 'method call' *syntax* ?

That's language dependent.

>Given the existence of
"computed attributes" (ie: support for 'attribute access' *syntax* with
hidden accessors) and the possibility to redefine implementation (from
default attribute r/w access to computed/controlled) without touching
the interface, why advocate the *systematic* use of computed attributes
when it's just duplicating the default behaviour ?

I'm not advocating anything.

cf below on this.
I'm just stating the use case for
accessors and the wisdom behind them. My qualm with implicit accessors
remains the name issue.

The "name issue" is *your* problem. And AFAICT, it's a "problem" because
you refuse to free your mind from a "what's in the book" mindset.
What book are we talking about?
>>>>For example, a third party randomly changing is_active, (which Python
lets you do freely and easily) from False to True may crash your GUI.
And I'm not making this up. Things like this do really happen depending
on the whackyness of your toolkit.

That's quite true, but a setter that does nothing but change is_active
doesn't prevent this. If there is logic necessary to prevent state changes
in certain situations, this should be implemented. But whether you then
call this a part of the "behavior" (looking at the implementation as being
a setter method) or a part of the "state" (looking at the implementation as
being an added feature of the attribute) doesn't really make an objective
difference.

Of course using setters for the sake of just using them is pointless.

Indeed.
The reason to use them is if pre-conditions or post-conditions need to
be met. Or to control access to an objects states.

Then why advocate *systematic* use of them ?

(snip)
I never advocated anything.

You advocated
"""
1). Make all attributes of a class private/protected .
2). If a "non-callable" attribute is going to be used outside a class,
think about making it a property and name the property well, because
you never know...
"""
You use accessors when you need to control access to a data attribute.
That's not advocacy, that's common sense.
>>State - behavior is not something I made up, so it isn't subjective.

The words (and the concept they describe) are not. Interpretation of
what is state and what is behaviour is subjective.
It
is a common term used in OO literature. In fact, the only reason I used
it is because I thought is was common knowledge.

It is.
And behaviors are not
just necessarily getters/setters, they are methods of objects.

Behaviour is how a given object reacts to a given message. *Nothing* in
this implies the notions of attributes or methods. Attributes and
methods are implementation details of the concepts of state and
behaviour, and - while this is a common implementation of OO concepts -
the choice to use non-callable attributes as representing the state
and callable ones as representing behaviour is totally
implementation-dependant.
I agree. And I already told you I think in terms of state and behavior
and not language dependent semantics.

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?

Jul 18 '06 #70

Bruno Desthuilliers wrote:
mystilleef wrote:
Bruno Desthuilliers wrote:
>mystilleef wrote:
<ot>Please don't top-post</ot>

On State and Behavior:

To understand objects in terms of state and behavior you need to
absolve yourself from implementation details of languages
and think at an abstract level.

Take a button object, for example. It has state and behavior. Possible
states may include, is_active, is_focused, is_mapped, etc. Behavior is
what the button does when it responds to events, (e.g when you click on
it, or drag it, or position a pointer over it.) If you've done any form
of event based programming (GUI/Games/Simulation), this method of
thinking becomes natural.

As you can see, when I'm designing a button object, I don't care what
Python does with is_active. I don't care how it accesses. I don't care
what is_active means to Python. I don't care about Python's __get__
/__set__ special/latent functions or implementation details. is_active
to me and every other developer is a state of the button object. And at
that level that's all that matters. Python can tell me it's just ones
and zeros for all I care.

In very well designed systems, the state of an object should only be
changed by the object.

... as a response to a message.
For example, a third party randomly changing
is_active, (which Python lets you do freely and easily)

Unless you make it a read-only property.
So you see the purpose of accessors then?

*where* did I say *anything* that could *possibly* be taken as me not
seeing the point of computed attributes ?

What I'm saying here is that it's totally useless to duplicate default
behaviour.
And who's doing that?
>>from False to
True may crash your GUI.

And I'm not making this up. Things like this
do really happen depending on the whackyness of your toolkit. So
sometimes, it is my duty to protect the state of an object. Especially
if its state cannot afford to be corrupted rendering the system
unstable. And situations like this are found a plenty in event based
programming. Which is programming objects based almost entirely on
state and behavior. As you can see this has nothing to do with Python
vs Java's vs X's implementation of accessors and how using them sucks,
or how they aren't Pythonic. Some domains just require this stuff.

Properties *are* 'accessors'.
I never said they weren't.

Fine.

Now : in a language with support for computed attributes, direct
attribute access is the default r/w accessors.
Depends on your definition of accessors. Otherwise 97% of languages
provide direct access to an object's data attributes.
>>One of the requirements for designing robust object systems is ensuring
the state of objects aren't easily contaminated.

"contaminated" ???
Make an object's state unreliable. See above example.

That's the word you choose that I find really strange.
What's strange about it. If an object's data attribute is supposed to
state that it is false when there are no mark objects in the buffer,
and a third party accidently incorrectly changes the attribute to state
it is True for whatever reasons, you essentially corrupt the objects
state and render the whole system "unreliable," or "buggy". What again
is difficult to grasp?
>>That "state" is the
objects data (read: stuff the object needs to do something "reliably").

Makes no sens to me.
is_active is an object's data,

class Obj(object):
# ....
@apply
def is_active():
def fget(self):
return (self.something and self.computeThis()) \
or self.otherCondition()
def fset(self, val):
raise ReadOnlyError()
def fdel(self):
raise UndeletableError()
return **locals()

According to *your* sayings, Obj.is_active is "behaviour"...
Not my saying. OO says so.
>>And this is why many overzealous OO languages do "force" you to use
accessors.

The only languages I know that "force" you to use accessors are
Smalltalk and Ruby (and Ruby offers some syntactic sugar for 'default' -
ie r/w - accessors).
Add Eiffel to the list. Java/C++/C#/Ada all recommend it by convention.

It's not because they hate you or aren't aware of the
>>convenience of having direct access to an object's attributes. It's
just because these languages convenience/robustness ratios are
different.

I'm afraid it has very few to do with "robustness".
Your opinion.
>>Thinking in terms of callable vs non-callable is not helpful for me,
because it isn't high level enough.

Allo, Huston ?
Thinking in terms of state and
behavior is, because it works regardless of programming language or
implementations. This is the reason I like working with Python. I
wanted a language that didn't bore me with it semantics and allowed me
to focus on design. Let me reiterate, I'm not obsessing over language
semantics, I just need practical, not religious, solutions for my
problem domain.

Using properties instead of explicit getters/setters is pragmatism, not
religion. Using the default get/set mechanism when there's no specific
reason to do otherwise is pragmatism too. And understanding the object
model and idioms of the language you're using is IMHO the very pragmatic
thing to do...
Again, the object model of the language is irrelevant.

Allo, Huston ?
The only
relevant model is my application's model, which should work regardless
of the language I use.

What to say...

....

Jul 18 '06 #71
mystilleef wrote, making me somewhat tired of his/her repeated inability
to get what's being said [sigh]:
Bruno Desthuilliers wrote:
>>mystilleef wrote:
>>>Bruno Desthuilliers wrote:
mystilleef wrote:
>Gerhard Fiedler wrote:
>>On 2006-07-15 06:55:14, mystilleef wrote:
>>>In very well designed systems, the state of an object should only be
>>>changed by the object.
>>
>>IMO that's not quite true. Ultimately, the state always gets changed by
>>something else (user interaction, physical events); very few objects are
>>completely self-contained in their behavior.
>>
>
>Then in those cases the system becomes a victim of high coupling.
This makes it somewhat obvious that you don't appear to fully understand
the concept of coupling as applied to software systems.
>>>>Time to burn your book and face reality. ObjA sends message Msg1 to
ObjB. Part of the associated behaviour is that in responce to Msg1, objB
changes it's own state. Practical result : ObjB's state has been changed
by ObjA. Practical question : how do you hope to avoid this "hi
coupling" (lol), apart from making all your objects totally autistic ?

Are you serious?

Deadly serious. But I'm afraid you're still missing the point.
>>>Well, you design an object that serves as a mediator.
All objects can then only interact with themselves and the mediator
only. Via signals, objects learn to automatically adjust their states
and respond to events.

signal -message -method call -change state.

Spell it how you like, add as many indirection levels you want, it still
boils down to the fact that *something* triggers the state change.
Riiiiight!
If you implement an accessor to change a class's instances' states,
surely something has to call that accessor. You seem to be implying that
such calls can only be made from within other methods of the same
object, which (if true, which it isn't) would tend to leave each class
in a vacuum where nothing else can affect its instances.

Of *course* objects are subject to external influences: since you like
the concept of coupling, how else could different components be coupled
at all?
>
>>>This is just one of several methods you can
dramatically reduce coupling.

It's just one of several methods that dramatically increases complexity,
without changing anything to the fact that in the end, *practically*,
some object ObjA changes its state as a response to a message sent by ObjB.
Say that to game/simulation developers.
This is a complete non-sequitur as you don't say why game developers
specifically benefit from the reduced coupling that you allege the
provision of accessor methods introduces.

Tight coupling would be (for example) where you provided the argument to
a method by storing it in a global variable rather than passing it as an
argument. From a coupling point of view it makes no difference whether
you call an accessor method or (in Python) read or write a referenced
object's attributes directly. You still have to know the required API:
whether you call a method (in which case you have to know its name) or
read/write an attribute (in which case you have to know its name ...)
makes no essential difference.

It appears you have seen the term "content coupling" as defined, for
example, in

http://en.wikipedia.org/wiki/Couplin...ter_science%29

and taken that to mean that any knowledge at all of another object's
internals will lead to over-tight coupling and hence low cohesion. The
Python point of view is somewhat different, and says that since both
methods and data items are attributes of instances there is little
difference (except in efficiency) between accessing data via a method
(inefficient) and accessing data directly through the attribute
containing that data (efficient).

It has already been pointed out to you several times that once you have
written your code to access attributes you can introduce properties
without changing the client (accessing) code should further isolation or
additional computation be required.
>
>>>I'm sure glad I didn't burn my book.

No comment.
>>>>>>In most systems (and you possibly have written some of them) are objects
>>whose state gets changed by other objects -- possibly through the
>>intermediation of setter methods that do nothing else but set the state.
>>There's no conceptual difference between directly setting the state or
>>calling a setter function that does nothing else but directly setting the
>>state -- except for one unnecessary level of indirection in the latter.
>
>It depends. If certain conditions need to be met before changing the
>state of an object, then arbitrarily changing it can be dangerous.

Does this imply a 'method call' *syntax* ?

That's language dependent.

Given the existence of
"computed attributes" (ie: support for 'attribute access' *syntax* with
hidden accessors) and the possibility to redefine implementation (from
default attribute r/w access to computed/controlled) without touching
the interface, why advocate the *systematic* use of computed attributes
when it's just duplicating the default behaviour ?

I'm not advocating anything.

cf below on this.
>>>I'm just stating the use case for
accessors and the wisdom behind them. My qualm with implicit accessors
remains the name issue.

The "name issue" is *your* problem. And AFAICT, it's a "problem" because
you refuse to free your mind from a "what's in the book" mindset.
What book are we talking about?
Well you should know, you're the one who wants to hang on to it. So
please enlighten us, what is this source of knowledge that appears to
contradict sound computer science?
>>>>>>>For example, a third party randomly changing is_active, (which Python
>>>lets you do freely and easily) from False to True may crash your GUI.
>>>And I'm not making this up. Things like this do really happen depending
>>>on the whackyness of your toolkit.
Whereas you appear to feel that there can be no possibility if a crash
because someone calls thing.is_active(True), and yet you repeatedly fail
to demonstrate the difference. Which is why this thread has been so
mind-numbingly long. As is pointed out AGAIN here:
>>>>>>
>>That's quite true, but a setter that does nothing but change is_active
>>doesn't prevent this. If there is logic necessary to prevent state changes
>>in certain situations, this should be implemented. But whether you then
>>call this a part of the "behavior" (looking at the implementation as being
>>a setter method) or a part of the "state" (looking at the implementation as
>>being an added feature of the attribute) doesn't really make an objective
>>difference.
>>
>Of course using setters for the sake of just using them is pointless.

Indeed.

>The reason to use them is if pre-conditions or post-conditions need to
>be met. Or to control access to an objects states.

Then why advocate *systematic* use of them ?

(snip)

I never advocated anything.

You advocated
"""
1). Make all attributes of a class private/protected .
2). If a "non-callable" attribute is going to be used outside a class,
think about making it a property and name the property well, because
you never know...
"""
You use accessors when you need to control access to a data attribute.
That's not advocacy, that's common sense.
Perhaps so, but you still refuse to explain why it's better, when all
you need to do is read or write the value of an instance's attribute, to
define accessor methods to do it, introducing unnecessary (in Python)
overhead in the process.
>
>>>>>State - behavior is not something I made up, so it isn't subjective.

The words (and the concept they describe) are not. Interpretation of
what is state and what is behaviour is subjective.

>It
>is a common term used in OO literature. In fact, the only reason I used
>it is because I thought is was common knowledge.

It is.
Am I the only one here who has lost track of this "'tis/'tisn't" stuff?
>>>>>And behaviors are not
>just necessarily getters/setters, they are methods of objects.

Behaviour is how a given object reacts to a given message. *Nothing* in
this implies the notions of attributes or methods. Attributes and
methods are implementation details of the concepts of state and
behaviour, and - while this is a common implementation of OO concepts -
the choice to use non-callable attributes as representing the state
and callable ones as representing behaviour is totally
implementation-dependant.

I agree. And I already told you I think in terms of state and behavior
and not language dependent semantics.

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?
In which case you write correct software and provide it with a thorough
set of tests to allow you to modify it without worrying too much about
breakage. Attribute access is part of an object's API just like method
calls are.

You seem to think that every ill in software design can be legislated
away by strangling design freedom with specific rules. I am afraid that
experience will teach you this is far from the case: go look at the way
that the "bondage" languages that use static typing (like Java and C++)
still fail to impose the required typing discipline on a determinedly
incompetent user.

As has already been said, the Python philosophy is to provide the
features that "consenting adults" (i.e. programmers who know what they
are doing) can use most effectively to produce complex software systems
to reasonable deadlines. Unfortunately not all the knowledge required to
do this is readily available in books; the rest must come from experience.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Jul 19 '06 #72
>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?
Ah, you mean like in JAVA where the compiler prevents you from accessing
private variables, but the runtime allows access to these very variables
via reflection?

Or in C++, where the malevolent programmer just removes the private
declarations in his compile run, and accesses the "private" data from your
object as if it was never declared that way?

You better forget thinking about these hilarious mechanisms of access
control as something that enforces security, and start thinking about them
as a convention that states "I told you not to tamper with this, you've
been warned" - which is done in python using a leading underscore. Or two.

Unless setting or getting a property implies code being run beside the
actual state change, there is absolutely no reason to use accessors. But I
fear this horse has been beaten to death in front of you so many times, yet
still you refuse to see it that way - so, go and use accessors if you like.
Nobody cares....
Diez
Jul 19 '06 #73
>What I'm saying here is that it's totally useless to duplicate default
>behaviour.

And who's doing that?
Somebody who uses setters that only set a property?
Diez
Jul 19 '06 #74
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.
Jul 19 '06 #75
mystilleef wrote:
Bruno Desthuilliers wrote:
>>mystilleef wrote:
(snip)
>>>>>
>Of course using setters for the sake of just using them is pointless.

Indeed.

>The reason to use them is if pre-conditions or post-conditions need to
>be met. Or to control access to an objects states.

Then why advocate *systematic* use of them ?

(snip)

I never advocated anything.

You advocated
"""
1). Make all attributes of a class private/protected .
2). If a "non-callable" attribute is going to be used outside a class,
think about making it a property and name the property well, because
you never know...
"""


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)
That's not advocacy, that's common sense.
I'm afraid we don't use the same definition of "common sense". Writing
useless code is not part of my definition of "common sense".

(snip)
>>>
I agree. And I already told you I think in terms of state and behavior
and not language dependent semantics.

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*.

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

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.

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).
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 19 '06 #76
[ZeD]
you mean sed :)
sed 's/oldName/newName/g' oldFile newFile
I used to be a Perl programmer :-)

perl -i.bak -pe 's/oldName/newName/g' *

As said, this is risky as oldName can be used in other contexts.

--
Tobias Brox, 69°42'N, 18°57'E
Jul 19 '06 #77
[Jason]
Nothing like being forced to write getters and setters in C++/Java
before you feel like shooting your source code. Please don't bring
this code-rage into Python.
"Code generation" springs into my mind. IMO, if the code needs to be
generated, the language is not sufficiently advanced.

--
Tobias Brox, 69°42'N, 18°57'E
Jul 19 '06 #78
mystilleef wrote:
Bruno Desthuilliers wrote:
>>mystilleef wrote:
(snip)
>>>>>For example, a third party randomly changing
>is_active, (which Python lets you do freely and easily)

Unless you make it a read-only property.
So you see the purpose of accessors then?

*where* did I say *anything* that could *possibly* be taken as me not
seeing the point of computed attributes ?

What I'm saying here is that it's totally useless to duplicate default
behaviour.


And who's doing that?
That's exactly what you recommended: "make all attributes
private/protected (...) If a data attribute might likely be an API,
think about controlling access to via "properties""

>>>>>from False to

>True may crash your GUI.

>And I'm not making this up. Things like this
>do really happen depending on the whackyness of your toolkit. So
>sometimes, it is my duty to protect the state of an object. Especially
>if its state cannot afford to be corrupted rendering the system
>unstable. And situations like this are found a plenty in event based
>programming. Which is programming objects based almost entirely on
>state and behavior. As you can see this has nothing to do with Python
>vs Java's vs X's implementation of accessors and how using them sucks,
>or how they aren't Pythonic. Some domains just require this stuff.

Properties *are* 'accessors'.
I never said they weren't.

Fine.

Now : in a language with support for computed attributes, direct
attribute access is the default r/w accessors.
Depends on your definition of accessors.
something that let me access an attribute.
Otherwise 97% of languages
provide direct access to an object's data attributes.
But not 97% of languages provide support for computed attributes.
>
>>>>>One of the requirements for designing robust object systems is ensuring
>the state of objects aren't easily contaminated.

"contaminated" ???
Make an object's state unreliable. See above example.

That's the word you choose that I find really strange.


What's strange about it. If an object's data attribute is supposed to
state that it is false when there are no mark objects in the buffer,
and a third party accidently incorrectly changes the attribute to state
it is True for whatever reasons, you essentially corrupt the objects
state and render the whole system "unreliable," or "buggy". What again
is difficult to grasp?
The choice of the word "contaminated".
>
>>>>>That "state" is the
>objects data (read: stuff the object needs to do something "reliably").

Makes no sens to me.
is_active is an object's data,

class Obj(object):
# ....
@apply
def is_active():
def fget(self):
return (self.something and self.computeThis()) \
or self.otherCondition()
def fset(self, val):
raise ReadOnlyError()
def fdel(self):
raise UndeletableError()
return **locals()

According to *your* sayings, Obj.is_active is "behaviour"...
Not my saying. OO says so.
Chapter and verse, please ?

now :
class Obj(object):
def __init__(self):
self.is_active = False

Now, 'is_active' is state again ?
>>>>>And this is why many overzealous OO languages do "force" you to use
>accessors.

The only languages I know that "force" you to use accessors are
Smalltalk and Ruby (and Ruby offers some syntactic sugar for 'default' -
ie r/w - accessors).


Add Eiffel to the list. Java/C++/C#/Ada all recommend it by convention.
Java/C++/C#/Ada all recommend it because they have no support for
computed attributes, which means that you cannot change implementation
without breaking the interface.

>
>>>It's not because they hate you or aren't aware of the

>convenience of having direct access to an object's attributes. It's
>just because these languages convenience/robustness ratios are
>different.

I'm afraid it has very few to do with "robustness".

Your opinion.
what's the exact difference in "robustness" between:

class DreamItisRobust(object):
def __init__(self):
self._attr = 42
def get_attr(self):
return self._attr
def set_attr(self, attr):
self._attr = attr

and

class DontCare(object):
def __init__(self):
self.attr = 42
???

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 19 '06 #79
Ant

Ed Jensen wrote:
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.
Yes it does. You can call setAccessible(true) on the Method object to
override the privateness.

Jul 19 '06 #80
On 2006-07-19 14:12:33, Tobias Brox wrote:
"Code generation" springs into my mind. IMO, if the code needs to be
generated, the language is not sufficiently advanced.
Isn't that just a question of level? I'm sure there are editors that
generate Python class stubs, GUI builders that generate Python GUI
frameworks, and so on. Nothing needs to be generated, but some things are
more convenient to write (for some people; convenience is quite subjective)
using generators.

Gerhard

Jul 19 '06 #81
Tobias Brox a écrit :
[Jason]
>>Nothing like being forced to write getters and setters in C++/Java
before you feel like shooting your source code. Please don't bring
this code-rage into Python.


"Code generation" springs into my mind. IMO, if the code needs to be
generated, the language is not sufficiently advanced.
OTOH, most decorators and metaclass hacking is somehow code generation -
but hopefully not at the source code level...
Jul 19 '06 #82
Ed Jensen schrieb:
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".
Now THAT was an important information RIGHT on topic.
>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.
For somebody nitpicking on natural language usage to a non-native
speaker, you show an impressive lack of knowledge in the actual subject
discussed.

http://www.onjava.com/pub/a/onjava/2...eflection.html
Diez
Jul 19 '06 #83
Bruno Desthuilliers wrote:
ZeD wrote:
Bruno Desthuilliers wrote:

>>I decided to change the name of an attribute. Problem is I've used the
attribute in several places spanning thousands of lines of code. If I
had encapsulated the attribute via an accessor, I wouldn't need to do
an unreliable and tedious search and replace

find and grep are usually mostly reliable for this kind of tasks.

you mean sed :)

No, I meant find and grep.
sed 's/oldName/newName/g' oldFile newFile
Yeah, fine - as long as your pretty sure the same name is not used in
other contexts in any of the source files...

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
I think that was the original point about find/replace: it can be
really hard to automate a name change, because changes might occur that
you didn't intend; whereas, doing things by hand lacks consistency.

My solution is to use emacs' query-replace (which you can invoke with
M-%). It will find quicly and accurately, but I ultimately hold the key
to whether something gets replaced or not.

Jul 20 '06 #84

Bruno Desthuilliers wrote:
mystilleef wrote:
Bruno Desthuilliers wrote:
>mystilleef wrote:
(snip)
>>>>
Of course using setters for the sake of just using them is pointless.

Indeed.

The reason to use them is if pre-conditions or post-conditions need to
be met. Or to control access to an objects states.

Then why advocate *systematic* use of them ?

(snip)

I never advocated anything.

You advocated
"""
1). Make all attributes of a class private/protected .
2). If a "non-callable" attribute is going to be used outside a class,
think about making it a property and name the property well, because
you never know...
"""

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.
That's not advocacy, that's common sense.

I'm afraid we don't use the same definition of "common sense". Writing
useless code is not part of my definition of "common sense".

(snip)
>>
I agree. And I already told you I think in terms of state and behavior
and not language dependent semantics.

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?
point 2 : so anyone *can* "illegimately tampering with an object's
internal data" at will.
And this is robust how?
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.
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.

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

See! I'm controlling access. 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. Also a naive third party won't crash
my system by changing Robust's state arbitrarily. Because in the real
world when your program is buggy, you get bug reports, nasty emails
among other forms of ridicule. And your supposed solution to my problem
is me saying, "but...but...I told you not change is_active." Ha! And if
you can't figure out why anyone would do this, then I'm not wasting my
time here anymore. Someday you'll learn the hard way.

Thanks to the people who exposed me to Python's properties.

Bye

Jul 20 '06 #85

Steve Holden wrote:
mystilleef wrote, making me somewhat tired of his/her repeated inability
to get what's being said [sigh]:
Bruno Desthuilliers wrote:
>mystilleef wrote:
Bruno Desthuilliers wrote:
mystilleef wrote:
Gerhard Fiedler wrote:
>On 2006-07-15 06:55:14, mystilleef wrote:
>>In very well designed systems, the state of an object should only be
>>changed by the object.
>
>IMO that's not quite true. Ultimately, the state always gets changed by
>something else (user interaction, physical events); very few objects are
>completely self-contained in their behavior.
>

Then in those cases the system becomes a victim of high coupling.
This makes it somewhat obvious that you don't appear to fully understand
the concept of coupling as applied to software systems.
>>>Time to burn your book and face reality. ObjA sends message Msg1 to
ObjB. Part of the associated behaviour is that in responce to Msg1, objB
changes it's own state. Practical result : ObjB's state has been changed
by ObjA. Practical question : how do you hope to avoid this "hi
coupling" (lol), apart from making all your objects totally autistic ?

Are you serious?

Deadly serious. But I'm afraid you're still missing the point.

Well, you design an object that serves as a mediator.
All objects can then only interact with themselves and the mediator
only. Via signals, objects learn to automatically adjust their states
and respond to events.

signal -message -method call -change state.

Spell it how you like, add as many indirection levels you want, it still
boils down to the fact that *something* triggers the state change.
Riiiiight!
If you implement an accessor to change a class's instances' states,
surely something has to call that accessor. You seem to be implying that
such calls can only be made from within other methods of the same
object, which (if true, which it isn't) would tend to leave each class
in a vacuum where nothing else can affect its instances.

Of *course* objects are subject to external influences: since you like
the concept of coupling, how else could different components be coupled
at all?
I gave the solution earlier. In well designed systems objects should be
responsible for updating their state themselves. In essence, objects
should learn to mind their own business. There will be some form of
coupling, but it should be minimal. Preferably the only coupling
permitted should be between an object and its mediator. Messages are
passed through the system via signals or events or established
protocols. What are the benefits? Well I can change the implementation
of any object at will without breaking the whole system. Or I can even
completely replace modules and objects with new ones without breaking
the whole system. If you are dealing with large source code, this is a
no brainer. And if you put a little effort into to it, you can create
objects that know when to initialize and destroy themselves as well as
update their states automatically. Welcome to event based programming.

(snip)
>>I'm sure glad I didn't burn my book.

No comment.

>In most systems (and you possibly have written some of them) are objects
>whose state gets changed by other objects -- possibly through the
>intermediation of setter methods that do nothing else but set the state.
>There's no conceptual difference between directly setting the state or
>calling a setter function that does nothing else but directly setting the
>state -- except for one unnecessary level of indirection in the latter.

It depends. If certain conditions need to be met before changing the
state of an object, then arbitrarily changing it can be dangerous.

Does this imply a 'method call' *syntax* ?

That's language dependent.

Given the existence of
"computed attributes" (ie: support for 'attribute access' *syntax* with
hidden accessors) and the possibility to redefine implementation (from
default attribute r/w access to computed/controlled) without touching
the interface, why advocate the *systematic* use of computed attributes
when it's just duplicating the default behaviour ?

I'm not advocating anything.

cf below on this.

I'm just stating the use case for
accessors and the wisdom behind them. My qualm with implicit accessors
remains the name issue.

The "name issue" is *your* problem. And AFAICT, it's a "problem" because
you refuse to free your mind from a "what's in the book" mindset.
What book are we talking about?
Well you should know, you're the one who wants to hang on to it. So
please enlighten us, what is this source of knowledge that appears to
contradict sound computer science?
High coupling is bad. Exposing critical states of an object is bad. Any
decent computer science book will tell you that.
>>>>>>For example, a third party randomly changing is_active, (which Python
>>lets you do freely and easily) from False to True may crash your GUI.
>>And I'm not making this up. Things like this do really happen depending
>>on the whackyness of your toolkit.

Whereas you appear to feel that there can be no possibility if a crash
because someone calls thing.is_active(True), and yet you repeatedly fail
to demonstrate the difference. Which is why this thread has been so
mind-numbingly long. As is pointed out AGAIN here:
>>>>>
>That's quite true, but a setter that does nothing but change is_active
>doesn't prevent this. If there is logic necessary to prevent state changes
>in certain situations, this should be implemented. But whether you then
>call this a part of the "behavior" (looking at the implementation as being
>a setter method) or a part of the "state" (looking at the implementation as
>being an added feature of the attribute) doesn't really make an objective
>difference.
>
Of course using setters for the sake of just using them is pointless.

Indeed.

The reason to use them is if pre-conditions or post-conditions need to
be met. Or to control access to an objects states.

Then why advocate *systematic* use of them ?

(snip)

I never advocated anything.

You advocated
"""
1). Make all attributes of a class private/protected .
2). If a "non-callable" attribute is going to be used outside a class,
think about making it a property and name the property well, because
you never know...
"""
You use accessors when you need to control access to a data attribute.
That's not advocacy, that's common sense.
Perhaps so, but you still refuse to explain why it's better, when all
you need to do is read or write the value of an instance's attribute, to
define accessor methods to do it, introducing unnecessary (in Python)
overhead in the process.
Obviously if I want to control access to an attribute, it means I don't
want it altered or I want to perform pre/post conditional computations
before/after the attribute is accessed. There's a reason it is called
access control.
>>>>State - behavior is not something I made up, so it isn't subjective.

The words (and the concept they describe) are not. Interpretation of
what is state and what is behaviour is subjective.

It
is a common term used in OO literature. In fact, the only reason I used
it is because I thought is was common knowledge.

It is.
Am I the only one here who has lost track of this "'tis/'tisn't" stuff?
>>>>And behaviors are not
just necessarily getters/setters, they are methods of objects.

Behaviour is how a given object reacts to a given message. *Nothing* in
this implies the notions of attributes or methods. Attributes and
methods are implementation details of the concepts of state and
behaviour, and - while this is a common implementation of OO concepts -
the choice to use non-callable attributes as representing the state
and callable ones as representing behaviour is totally
implementation-dependant.

I agree. And I already told you I think in terms of state and behavior
and not language dependent semantics.

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?
In which case you write correct software and provide it with a thorough
set of tests to allow you to modify it without worrying too much about
breakage. Attribute access is part of an object's API just like method
calls are.
Or I use accessors. Because I write tests doesn't mean third parties do
so, or even uphold the practice.
You seem to think that every ill in software design can be legislated
away by strangling design freedom with specific rules. I am afraid that
experience will teach you this is far from the case: go look at the way
that the "bondage" languages that use static typing (like Java and C++)
still fail to impose the required typing discipline on a determinedly
incompetent user.
Well I disagree. I used to share you mentality until I started managing
large source code. You need rules if you don't want your project to
collaspe under anarchy. And it is not until other people start using
your software in ways you never imagined that you realize the
importance of designing robust implementations upfront. When I wrote
less than a 1000 lines of Python code, I didn't care for
properties/accessors/public/private states or whatever. And I drank all
the Python philosophy cool aid I could get. But when you begin to get
emails about bugs in your software due to a third party inadvertently
changing states you never bothered to hide to begin with, then the
wisdom behind careful upfront planning begins to make sense.
As has already been said, the Python philosophy is to provide the
features that "consenting adults" (i.e. programmers who know what they
are doing) can use most effectively to produce complex software systems
to reasonable deadlines. Unfortunately not all the knowledge required to
do this is readily available in books; the rest must come from experience.
That's all fine and dandy in the fantasy world. In the real world,
consenting adults do stupid things, and if I can prevent them from
doing it, especially when it affects me, I bloody well will.

Jul 20 '06 #86
In <11**********************@h48g2000cwc.googlegroups .com>, mystilleef
wrote:
>
Bruno Desthuilliers wrote:
>mystilleef wrote:
Bruno Desthuilliers wrote:

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 have a tool to change the default accessor into something more
complicated, a calculated attribute, without the need to change the API.
>point 2 : so anyone *can* "illegimately tampering with an object's
internal data" at will.

And this is robust how?
That's as robust as the consenting adults that use that code. And as
robust as Java where you can get at private attributes via reflection and
C++ where you can simply define private as public.
>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.
No he's not joking. If programmers don't read the "stop here, this is
internal" signs and carelessly change states then there's a much bigger
problem than access control. The problem is with the programmer, not the
language.
>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.

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

See! I'm controlling access. Whee!
No you don't.

obj = Robust()
obj._Robust__is_active = 42

The name munging is not meant to provide access control but to avoid name
clashes when dealing with deep inheritance hierarchies or mixin classes.

A pythonista would just call the attribute `_is_active` and rely on the
common sense of other programmers not to play with it at will.
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.
If it's called `_is_active` then the access to it should not be spread
over 27000 lines. You don't access attributes not belonging to the API
from everywhere in the code base. If you do, you are a bit careless as a
programmer, don't you think?
Also a naive third party won't crash my system by changing Robust's
state arbitrarily. Because in the real world when your program is buggy,
you get bug reports, nasty emails among other forms of ridicule. And
your supposed solution to my problem is me saying, "but...but...I told
you not change is_active."
The name `_is_active` tells that it's not API. If the naĂŻve third party
does not respect this than it's on its own. The solution is indeed to
tell that to them because otherwise they will get into trouble when they
continue to program in Python where this is the common way to make things
"private".
Ha! And if you can't figure out why anyone would do this, then I'm not
wasting my time here anymore. Someday you'll learn the hard way.
You shouldn't waste your time with Python then. The language is obviously
not "bondage" enough for your needs.

Ciao,
Marc 'BlackJack' Rintsch
Jul 20 '06 #87
Dennis Lee Bieber wrote:
On 19 Jul 2006 22:38:17 -0700, "mystilleef" <my********@gmail.com>
declaimed the following in comp.lang.python:

>>permitted should be between an object and its mediator. Messages are
passed through the system via signals or events or established
protocols. What are the benefits? Well I can change the implementation
of any object at will without breaking the whole system. Or I can even


Python permits that using properties... But one doesn't have to code
the properties from the get-go... Development can be done with direct
attribute access, and if it is determined that some sort of conditioning
logic is needed, it can be implemented WITHOUT CHANGING THE API.

This IS an "established protocol" in Python.
>>High coupling is bad. Exposing critical states of an object is bad. Any
decent computer science book will tell you that.

In Python, using, if needed, properties, this is transparent... The
user of the object doesn't know, or need to know, if it is state or
behavior -- all it sees is that it supplies a value for something,
and/or retrieves a value for something.
>>Obviously if I want to control access to an attribute, it means I don't
want it altered or I want to perform pre/post conditional computations
before/after the attribute is accessed. There's a reason it is called
access control.

Python properties support this, no need to have the user of the
object explicitly call a getter or setter...
>>changing states you never bothered to hide to begin with, then the
wisdom behind careful upfront planning begins to make sense.

If it isn't part of the documented API, it is the user's fault. That
applies to all software...
I'm this thread represents proof tht you can lead a horse to water but
you can't make him drink - especially when he thinks the water is
Kool-Aid, and that attribute APIs can be abused in ways that
method-based ones can't.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Jul 20 '06 #88
mystilleef wrote:
[...]
>
I don't know it's your code not mine.

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")
Let's ignore changes of state for the moment. The mystical difference
that makes read access via

some_robust.buffer_is_active()

acceptable and

some_robust.__is_active

somehow dangerous (ignoring the fact that name_mangling will take place)
is what?
def monitor_events(self):
# Only methods of this class can change __is_active.
# Add code to change __is_active here.
return
I'm sure nobody would argue that if close synchronization between
multiple attributes is required then write accessors are a bad idea. But
using them unnecessarily just makes your code heavier, slower and less
easy to maintain.
See! I'm controlling access. 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. Also a naive third party won't crash
my system by changing Robust's state arbitrarily. Because in the real
world when your program is buggy, you get bug reports, nasty emails
among other forms of ridicule. And your supposed solution to my problem
is me saying, "but...but...I told you not change is_active." Ha! And if
you can't figure out why anyone would do this, then I'm not wasting my
time here anymore. Someday you'll learn the hard way.
It's way too late. My comments *are* based on engineering experience.
One day you may realise that unnecessary complexity is a far bigger time
waster than any imagined problems of direct attribute access. I suspect
that if you are getting complaints if the nature you describe it's just
because your software isn't that good.
Thanks to the people who exposed me to Python's properties.

Bye
Really? Promise? I fear we are arguing from different premises.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Jul 20 '06 #89
Steve Holden wrote:
mystilleef wrote:
[...]

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

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")
Let's ignore changes of state for the moment. The mystical difference
that makes read access via

some_robust.buffer_is_active()
buffer_is_active is not a method, it's a property. So:

some_robust.buffer_is_active

is appropriate.
acceptable and

some_robust.__is_active

somehow dangerous (ignoring the fact that name_mangling will take place)
is what?
We can't ignore name mangling. That's an illegal statement in Python.
So it is less dangerous.
def monitor_events(self):
# Only methods of this class can change __is_active.
# Add code to change __is_active here.
return
I'm sure nobody would argue that if close synchronization between
multiple attributes is required then write accessors are a bad idea. But
using them unnecessarily just makes your code heavier, slower and less
easy to maintain.
Ah, I broke my own rule. That method is supposed to be private too.
Meaning no one can change the state of the object except the object
itself. The code is below

def __monitor_event(self):
# Perform whatever needs to be done to change state
return

__monitor_event is not supposed to be a write accessor. My point was
show how you can change the state of an object internally without
needing external access to it. Since some people are surprisingly
claiming it is not possible.
See! I'm controlling access. 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. Also a naive third party won't crash
my system by changing Robust's state arbitrarily. Because in the real
world when your program is buggy, you get bug reports, nasty emails
among other forms of ridicule. And your supposed solution to my problem
is me saying, "but...but...I told you not change is_active." Ha! And if
you can't figure out why anyone would do this, then I'm not wasting my
time here anymore. Someday you'll learn the hard way.
It's way too late. My comments *are* based on engineering experience.
One day you may realise that unnecessary complexity is a far bigger time
waster than any imagined problems of direct attribute access. I suspect
that if you are getting complaints if the nature you describe it's just
because your software isn't that good.
And mine are based on future engineering predictions? Okay, one day I
shall see the light.
Thanks to the people who exposed me to Python's properties.

Bye
Really? Promise? I fear we are arguing from different premises.
Yes, we are. We have been since about the 5th post on this thread if
you haven't noticed.

Jul 20 '06 #90
mystilleef wrote:
Bruno Desthuilliers wrote:
>>mystilleef wrote:
>>>Bruno Desthuilliers wrote:
mystilleef wrote:

(snip)
>>>>>>>Of course using setters for the sake of just using them is pointless.
>>
>>Indeed.
>>
>>
>>
>>
>>>The reason to use them is if pre-conditions or post-conditions need to
>>>be met. Or to control access to an objects states.
>>
>>Then why advocate *systematic* use of them ?
>>
>>(snip)
>
>I never advocated anything.

You advocated
"""
1). Make all attributes of a class private/protected .
2). If a "non-callable" attribute is going to be used outside a class,
think about making it a property and name the property well, because
you never know...
"""

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...
>
>>>That's not advocacy, that's common sense.

I'm afraid we don't use the same definition of "common sense". Writing
useless code is not part of my definition of "common sense".

(snip)
>>>>>I agree. And I already told you I think in terms of state and behavior
>and not language dependent semantics.

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.
>
>>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++.
>>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.
>
>>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.
>
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

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' ?
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.
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 ?

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.

[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"

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.
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
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.
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.
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).

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 20 '06 #91
Dennis Lee Bieber wrote:
On Wed, 19 Jul 2006 18:54:55 +0200, Bruno Desthuilliers
<on***@xiludom.grodeclaimed the following in comp.lang.python:

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

Pardon, but for the sense you intend, it should be:

... don't need, too?
Granted. Actually, it *was* a typo - but it happened to also make sens,
so I decided it was not a typo !-)

But I promise I'll be more carefull next time.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 20 '06 #92
On 2006-07-20 04:15:33, Steve Holden wrote:
mystilleef wrote:
[...]
>>
I don't know it's your code not mine.

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")
Let's ignore changes of state for the moment. The mystical difference
that makes read access via

some_robust.buffer_is_active()

acceptable and

some_robust.__is_active

somehow dangerous (ignoring the fact that name_mangling will take place)
is what?
> def monitor_events(self):
# Only methods of this class can change __is_active.
# Add code to change __is_active here.
return
I'm sure nobody would argue that if close synchronization between
multiple attributes is required then write accessors are a bad idea. But
using them unnecessarily just makes your code heavier, slower and less
easy to maintain.
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? It seems to me that
this is what mystilleef is trying to do.

I know that Python doesn't really provide access control. But so far I've
learned that a leading underscore says "I'm implementation, don't touch me
unless you know what you're doing". So I imagine that I browse through code
and look for leading underscores for non-local object attributes, to spot
troublespots. So I imagine that using such attributes as "read-only"
interface elements may not be a good idea, because then you not only have
to spot them in outside code, you always also have to check whether that's
a read or a write access (to know whether it's something potentially
dangerous or not). I also don't know how you could use the computed
attribute methods to do different things for access from the outside and
from the inside (of the object).

So... _is_active is considered implementation. Don't mess with me, it says.
But the users of the class need access to it: read access. Do you just say
"read access isn't changing anything, so just use _is_active"? The
disadvantage is that the outside code is sprinkled with accesses to
attributes with leading underscores, which I assume looks kind of scary. Or
do you rename _is_active to is_active, indicating that access to it is
indeed allowed? Then you would have to do something in the attribute
accessors to control the write access -- because that still isn't a good
idea. But I need want to be able to write to it from inside the class...
but how, if the attribute accessor is preventing that? Is there a local
override for that? I'm sure there is... but is it a common technique?

I may have not used the correct terminology for everything, but I think
it's possible to parse that :)

And maybe that helps putting this to rest and make everybody happy :)

Gerhard

Jul 20 '06 #93
Gerhard Fiedler wrote:
On 2006-07-20 04:15:33, Steve Holden wrote:

>>mystilleef wrote:
[...]
>>>I don't know it's your code not mine.

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")

Let's ignore changes of state for the moment. The mystical difference
that makes read access via

some_robust.buffer_is_active()

acceptable and

some_robust.__is_active

somehow dangerous (ignoring the fact that name_mangling will take place)
is what?

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

I'm sure nobody would argue that if close synchronization between
multiple attributes is required then write accessors are a bad idea. But
using them unnecessarily just makes your code heavier, slower and less
easy to maintain.


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? It seems to me that
this is what mystilleef is trying to do.

I know that Python doesn't really provide access control. But so far I've
learned that a leading underscore says "I'm implementation, don't touch me
unless you know what you're doing". So I imagine that I browse through code
and look for leading underscores for non-local object attributes, to spot
troublespots. So I imagine that using such attributes as "read-only"
interface elements may not be a good idea, because then you not only have
to spot them in outside code, you always also have to check whether that's
a read or a write access (to know whether it's something potentially
dangerous or not). I also don't know how you could use the computed
attribute methods to do different things for access from the outside and
from the inside (of the object).

So... _is_active is considered implementation. Don't mess with me, it says.
But the users of the class need access to it: read access. Do you just say
"read access isn't changing anything, so just use _is_active"? The
disadvantage is that the outside code is sprinkled with accesses to
attributes with leading underscores, which I assume looks kind of scary. Or
do you rename _is_active to is_active, indicating that access to it is
indeed allowed? Then you would have to do something in the attribute
accessors to control the write access -- because that still isn't a good
idea. But I need want to be able to write to it from inside the class...
but how, if the attribute accessor is preventing that? Is there a local
override for that? I'm sure there is... but is it a common technique?

I may have not used the correct terminology for everything, but I think
it's possible to parse that :)

And maybe that helps putting this to rest and make everybody happy :)
The logical way would seem to be to provide a read property is_active()
only. The implementation can access the _is_active instance variable
that the property exposes, writing it as necessary. If the accessor
gives direct access to the variable there's no need to use it inside the
object implementation. Or have I misunderstood your requirements?

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Jul 20 '06 #94
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.

To second that:

"""
A Foolish Consistency is the Hobgoblin of Little Minds
"""

http://www.python.org/dev/peps/pep-0008/
Diez
Jul 20 '06 #95
mystilleef wrote:
(snip)
>
__monitor_event is not supposed to be a write accessor. My point was
show how you can change the state of an object internally without
needing external access to it. Since some people are surprisingly
claiming it is not possible.
I failed to see anyone making such a claim.

(snip)
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 20 '06 #96
Gerhard Fiedler wrote:
(snip)
>
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())
(snip)
So... _is_active is considered implementation. Don't mess with me, it says.
But the users of the class need access to it: read access. Do you just say
"read access isn't changing anything, so just use _is_active"?
Certainly not.
The
disadvantage is that the outside code is sprinkled with accesses to
attributes with leading underscores, which I assume looks kind of scary. Or
do you rename _is_active to is_active, indicating that access to it is
indeed allowed?
Certainly not (given I want is_active to be read-only).
Then you would have to do something in the attribute
accessors to control the write access -- because that still isn't a good
idea. But I need want to be able to write to it from inside the class...
but how, if the attribute accessor is preventing that?
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.

HTH
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 20 '06 #97

Bruno Desthuilliers wrote:
mystilleef wrote:
Bruno Desthuilliers wrote:
>mystilleef wrote:

Bruno Desthuilliers wrote:
mystilleef wrote:

(snip)

>>Of course using setters for the sake of just using them is pointless.
>
>Indeed.
>
>
>
>
>>The reason to use them is if pre-conditions or post-conditions need to
>>be met. Or to control access to an objects states.
>
>Then why advocate *systematic* use of them ?
>
>(snip)

I never advocated anything.

You advocated
"""
1). Make all attributes of a class private/protected .
2). If a "non-callable" attribute is going to be used outside a class,
think about making it a property and name the property well, because
you never know...
"""

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.
>>That's not advocacy, that's common sense.

I'm afraid we don't use the same definition of "common sense". Writing
useless code is not part of my definition of "common sense".

(snip)

I agree. And I already told you I think in terms of state and behavior
and not language dependent semantics.

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?
>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!
>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.
>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.

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 to make yourself feel happy. 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. But I
don't have time to deal with fantasy and unreleastic theories.
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.
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, guess
who's gonna get the emails and bug reports? That's right you! And that
is after hours of trying to reproduce the bug on your system
unsuccessfully 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. Welcome to reality.
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.
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.
>
[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. Again, I'm
glad you are seeing success in __your__ projects.
>
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 actually requires more code, is looks complex and it's
ugly (no offense, my opinion).
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.
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. You don't know my
background with any language so quit this "Java is the reason you think
like this" banter.
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. There's only
so much books can do when it comes to designing robust software in
practice. 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.
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.

Jul 20 '06 #98
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.
>>>>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.
>
>>>>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.
>>>>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.
>>>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...
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).
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.
>
>>>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.
guess
who's gonna get the emails and bug reports? That's right you!
And ?
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.
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 ?"

>>>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.
>>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.
>
>>>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.
>
>>>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.
>
>>>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.

>
>>>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.
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 ?

>>>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.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Jul 20 '06 #99
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! That slipped my attention over all this noisy and pointless
discussion...

Regards,

Diez
Jul 20 '06 #100

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: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
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: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
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
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
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...

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.