Accessors in Python (getters and setters)

mystilleef mystilleef at gmail.com
Thu Jul 13 07:19:37 EDT 2006


Bruno Desthuilliers wrote:
> mystilleef wrote:
> > Bruno Desthuilliers wrote:
> >
> >>mystilleef wrote:
> >>
> >>>Lousy Attribute Name:
> >>>	self.tmp
> >>>
> >>>Accessors:
> >>>	set_temporary_buffer
> >>>	get_temporary_buffer
> >>>
> >>>The attribute name I chose, "tmp" sucks.
> >>
> >>Well, it's surely not as descriptive as 'temporary_buffer'
> >>
> >>
> >>>I have used that name in
> >>>dozens of places spanning over 27000 LOC.
> >>
> >>Too bad for you.
> >
> >
> > Thank you, that was helpful.
>
> What am I supposed to say ? You choose a bad name for a public symbol,
> used it in 27000 lines of Python code (which certainly took some time to
> write),

This is a __baseless__ statement. For all you know I could have used
the attribute twice in those 27000 lines of code. Even then searching
for and replacing the attribute is tedious and error prone.

>and all of a sudden you realize the name is bad and proceed to
> fix the problem.

Yes, the same way many programmers suddenly realize their class,
function, method, project, etc is poorly designed even after using it
for months and proceed to fix the problem. Shit happens.

>If you know of any other way than a massive
> find/replace, please share.

I wouldn't have started the topic if I did. Apparently the only
solution is to rereference the attribute with a better name and pray
and hope third party developers will use the better name. Or search and
replace!

>But blaming the language for your error won't help.

I did no such thing, you are making that up.

>
> >
> >>>There's a chance that other
> >>>develops might misinterpret exactly what "tmp" does. Plus I don't want
> >>>emails from other developers querying me about what "tmp" is/does.
> >>>"tmp" is obvious to me, but not necessarily to others.
> >>
> >>So why did you name it that way at first ?
> >>
> > What does it matter? There are 10 million and one reasons from given
> > identifiers bad names.
>
> And how many reasons to use a bad name in 27000 LOCs before deciding to
> fix the problem ?
>

Do you really think I used the name 27000 times in 27000 lines of code?
Maybe I'm not making myself clear. Having to search 27000 lines of code
to replace an identifier name is tedious and error prone.

> >>>Now compare that
> >>>to the accessors.
> >>
> >>But 'tmp' actually *is* an accessor.
> >
> >
> > I didn't say it wasn't.
>
> Yes you did. May I quote ?
> """
> "tmp" is obvious to me, but not necessarily to others. Now compare that
> to the accessors. Not only do they improve readability at the expense
> of more code, they actually allow me to change the lousily named
> attribute "tmp" to "temporary_buffer" without grepping, seding,
> searching, replacing and praying.
> """
>
> This obviously implies that you don't understand 'tmp' as being an accessor.
>

You are quoting me out of context. I was speaking with respect to real
accessors, not Python's latent implementation mechanisms.

> >>>Not only do they improve readability
> >>
> >>Err... do you find:
> >>
> >>obj.set_temporary_buffer(val)
> >>val = obj.get_temporary_buffer()
> >>
> >>really more readable than:
> >>
> >>obj.temporary_buffer = val
> >>val = obj.temporary_buffer
> >
> >
> > I didn't name the attribute temporary_buffer, I named it tmp.
>
> You didn't name the *accessor* 'temporary_buffer', you named it 'tmp'.
> You are *exactly* in the same situation as if you had used getter/setter
> named "get_tmp" and 'set_tmp". And your point about getters/setters
> "improving readability" is moot.
>

No I'm not. Naming attributes and naming methods are entirely different
situations.

> >
> >>>at the expense
> >>>of more code,
> >>
> >>Indeed. In both the class and client code.
> >>
> >>
> >>>they actually allow me to change the lousily named
> >>>attribute "tmp" to "temporary_buffer" without grepping, seding,
> >>>searching, replacing and praying.
> >>
> >>You still fail to get the point. You actually choose a crappy name for a
> >>*public* property. It's *exactly* as if, in Java, you had named your
> >>getter/setter 'get_tmp' and 'set_tmp'.
> >>
> >
> > No, it isn't.
>
> May I quote what wou wrote a few lines above in this very same post ?
> """
> >>But 'tmp' actually *is* an accessor.
> >
> >
> > I didn't say it wasn't.
> """
>
> Don't you see any contradiction here ?
>
> > In Java there's a clear distinction between attributes
> > and methods.
>
> Yes, and that's a big weakness of Java. But that's another point, and
> absolutely irrelevant here. Failing to understand a language semantics
> gives no right to complain about the language.
>

I never complained about either languages. You are making that up.

>
> >>>Sure, if you are dealing with less
> >>>than a 1000LOC you can get away with using "tmp" or renaming it easily.
> >>>But if you are dealing with a much larger code base and more
> >>>developers, issues like this rapidly become a nuisance.
> >>
> >>Indeed. But it's *your* responsability to choose good names for the API.>
> >
> > I choose good names for most of my APIs. But there cases when you never
> > know an attribute will actually be an API before hand.
>
> Then don't make it part of the API. And anyway, 27000 lines of Python
> take some time to write, so you had the opportunity to address the
> problem long ago - FWIW, you could have fixed it as soon as you noticed
> you were accessing this attribute in client code.
>

Yes, I fixed it then. Which was 27000 lines of code later.

> >
> >>>Yes, it is possible to name crappy accessors too (e.g set_tmp/get_tmp).
> >>
> >>or 'tmp'.
> >>
> >>
> >>>But developers tend to pay more attention to given methods/functions
> >>>less crappy names, at least when compared to data attributes.
> >>
> >>s/developpers/you/>
> >
> > Ha, right! I bet you are perfect developer.
>
> Certainly not, but I wouldn't confuse my own problems with a general
> rule. Note FWIW that I wouldn't blame a language (or my lack of
> understanding of that language) for my own errors.
>

Can you point me to exactly where I blamed Python for anything?

> >>>This
> >>>stems from the fact that in many languages data attributes aren't
> >>>usually part of the API,
> >>
> >>Once again, in Python, there is *no* such thing as 'data attributes'.
> >>*All* attributes are *objects* - some of them callable.
> >>
> > I didn't say attributes weren't objects.
>
> Nope, but you constantly bring that false "data/method" dichotomy in
> your justifications for having badly named a public symbol.
>

There is a dichotomy between data and methods. Yes even in Python.

> >
> >>>as well as the whole OO(Encapsulation) blah
> >>>blah.
> >>
> >>Don't confuse encapsulation with data-hiding.
> >
> > I don't see the confusion.
>
> Was just an advice against a very common mistake.
>
> >>>I know I would not name the accessors set_tmp/get_tmp, because my
> >>>philosophy is that methods/functions need to have meaningful names and
> >>>state their intended purpose.
> >>
> >>That's true for each and every name in a program.
> >>
> >>
> >>>I don't hold data attributes to such
> >>>standards
> >>
> >>Too bad for you.
> >>
> > Thank you.
>
> For what ? You "don't hold data attributes to such standard". As a
> consequence (and as a result of not having addressed the problem
> sooner), you end up fixing 27000 lines of code. Too bad for you then.
> Some would haved learned from the mistake, which then would have turned
> into experience. Seems more and more obvious that you prefer to come
> whining here instead and blaming the language for your own errors. Too
> bad for you again.
>

That's just silly. I openly admitted to making a mistake. I asked a
query as how to prevent such mistakes in the future, and all I get is
how I'm a dumb programmer and how Python is not Java and how I'm not
intelligent among other rubbish, and how I'm at fault, yaddi yadda.
Only two people actually took the time to "address" my problem.

> >
> >>>and I imagine many developers don't either and least based on
> >>>other people's code I've read. Plus there are many occassions when
> >>>attributes are not intended to be APIs,
> >>
> >>Then mark them as being implementation (ie : prefix them with a single
> >>underscore).
> >
> > I thought that too was unpythonic.
>
> It's a well-known convention, as you would have noticed if you had read
> some existing python code, read PEP8, or just looked/asked for Python
> naming conventions. FWIW, that's one of the first thing I learned with
> Python.
>

I know. Many people still think the private/public classification is
unpythonic.

> >>>but eventually become one.
> >>>After all most data attributes are created with the purpose of serving
> >>>methods.
> >>
> >>Nope. You have the class API, and the class implementation. Both made of
> >>both callable and non-callable attributes.
> >>
> >
> > Or objects have state and behavior. Data attributes represent state and
> > methods represent behavior.
>
> Is a getter "behaviour" ? If yes, how does this differ from public
> "data" attributes from a semantic POV ?
>

Yes, a getter is a behavior. It instructs the object to perform an
action. All methods are message channels to an object. A data attribute
does not perform any action. It just holds data for an object. Even
though methods are attributes, attributes aren't necessarily methods.
This is basic OO, I don't see anything semantically complex about it.

>
> >>Mystilleef, I do share your pain (really - been here, done that,
> >>etc...), and I understand that grasping Python requires some mental
> >>adjustments when coming from Java and friends (been here, done that,
> >>etc...). But you seriously can't blame the language for your own mistakes.
> >
> > You don't share my pain.
>
> Are you me to know what I feel ?
>
> > You seem to mock it.
>
> Compassion doesn't imply agreeing on wrong arguments.
>
> > I'm not new to Python
> > either.
>
> New enough to not understand how Python's object model, semantic and
> overall philosophy strongly differs from Java/C++.
>

This isn't an issue about object models and semantics, this is a
design/architecture issue with regards to eliminating the chances of
errors in large source code.

> > I've been using it for over 2 years in several capacities. I
> > only recently decided to use it for a large project.
> >
> >>If you intented 'tmp' to be part of the API, then you're responsible for
> >>the bad naming.
> >
> >
> > I never intended it to be part of the API.
>
> So you should not have used it outside the class.
>

The fact that I did, means I should have.

> > It evolved to be an
> > important part of the system.
>
> Then you had plenty of occasions to address the problem.
>

And how did you come up with that?

> >
> >>If you didn't, then you're responsible for breaking the
> >>encapsulation - FWIW, following the convention (single leading
> >>underscore) could have make it clearer to you.
> >>In both cases, you
> >>happily used a bad name in 27 KLOC - so you really had a lot of time and
> >>occasions to notice something wrong with this.
> >>
> >
> > That's nonsense.
>
> Your opinion. Facts tell otherwise.
>

What facts?

> > I only just noticed because I was trying to implement
> > a plug-in system and I needed to expose an important class. I would not
> > have considered the issue a problem without this requirement. Except
> > you are a prophet, you sometimes can't know before hand how certain
> > classes will end up being used especially if requirements suddenly
> > change.
>
> Yes, that's something I'm well aware of. And that's why I pay attention
> to naming and to interface/implementation separation.
>

Good for you.

> > Saying it's my fault to make yourself feel better about your
> > favorite language doesn't help solve my problem.
>
> I don't say it's your fault to "make (myself) feel better about (my)
> favorite language, but because the problem is entirely and only yours.
> Python has it's share of warts, and I'm not denying it.
>
> > I didn't come here to
> > be berated.
>
> Nope, but you came here blaming the language for your own errors, and
> constantly refuse to aknowledge that *you* got it wrong.
>
> > I came here to learn the Pythonic way to implementing
> > accessors.
>
> With public attributes when there's no processing to do, with computed
> attributes (based on descriptors, property being the most commonly used)
> else. But this is totally unrelated to the issue with badly chosen
> public names.
>
> > And of course how to deal with issues like the one I have in
> > medium size to large scale projects. People make mistakes, we deal with
> > an move on.
>
> When one makes mistake, one can either choose to aknowledge the fact and
> learn from it, or to find something/someone else to blame and not learn
> anything.
>

I still don't know what or who I blamed.




More information about the Python-list mailing list