Accessors in Python (getters and setters)

Bruno Desthuilliers onurb at xiludom.gro
Thu Jul 20 10:47:52 EDT 2006


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 'onurb at xiludom.gro'.split('@')])"



More information about the Python-list mailing list