A
Ant
Ed said: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.
Ed said:Java does not allow access to private members via reflection.
"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 -[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.
Ed said:Java is not an acronym. That is: it's "Java", not "JAVA".
Java does not allow access to private members via reflection.
Bruno said:No, I meant find and grep.
Yeah, fine - as long as your pretty sure the same name is not used in
other contexts in any of the source files...
Bruno said:Indeed. And when you don't need too ? (the second 'o' is not a typo)
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)
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).
Steve said:mystilleef wrote, making me somewhat tired of his/her repeated inability
to get what's being said [sigh]:This makes it somewhat obvious that you don't appear to fully understand
the concept of coupling as applied to software systems.
If you implement an accessor to change a class's instances' states,Riiiiight!
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?
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?
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:
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.
Am I the only one here who has lost track of this "'tis/'tisn't" stuff?
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.
Pardon, but for the sense you intend, it should be:Indeed. And when you don't need too ? (the second 'o' is not a typo)
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
In Python, using, if needed, properties, this is transparent... TheHigh coupling is bad. Exposing critical states of an object is bad. Any
decent computer science book will tell you that.
Python properties support this, no need to have the user of theObviously 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.
If it isn't part of the documented API, it is the user's fault. Thatchanging states you never bothered to hide to begin with, then the
wisdom behind careful upfront planning begins to make sense.
mystilleef said:Huh? What are properties for then?
And this is robust how?
You can't be serious. Please tell me you are joking.
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.
Dennis said: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.
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.
Python properties support this, no need to have the user of the
object explicitly call a getter or setter...
If it isn't part of the documented API, it is the user's fault. That
applies to all software...
Let's ignore changes of state for the moment. The mystical differenceI 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")
I'm sure nobody would argue that if close synchronization betweendef monitor_events(self):
# Only methods of this class can change __is_active.
# Add code to change __is_active here.
return
It's way too late. My comments *are* based on engineering experience.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.
Really? Promise? I fear we are arguing from different premises.Thanks to the people who exposed me to Python's properties.
Bye
Steve said:mystilleef wrote:
[...]Let's ignore changes of state for the moment. The mystical differenceI 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")
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?
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.
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.
Really? Promise? I fear we are arguing from different premises.
mystilleef said:You make the attribute private/protected.
Huh? What are properties for then?
And this is robust how?
You can't be serious. Please tell me you are joking.
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
Yuck.
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.
Dennis said:Pardon, but for the sense you intend, it should be:
... don't need, too?
mystilleef wrote:
[...]Let's ignore changes of state for the moment. The mystical differenceI 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")
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?
I'm sure nobody would argue that if close synchronization betweendef monitor_events(self):
# Only methods of this class can change __is_active.
# Add code to change __is_active here.
return
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.
The logical way would seem to be to provide a read property is_active()Gerhard said: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
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.
__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'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?
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?
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.