Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Defining accessor methods

3 views
Skip to first unread message

Graham Ashton

unread,
Jun 25, 2001, 4:48:23 AM6/25/01
to
I've been trying to come up with an idiom for defining accessor methods,
as outlined here:

http://www.object-arts.com/EducationCentre/Patterns/AccessorMethods.htm

I don't think that my knowledge of Python is quite there yet though. I've
got as far as:

def my_attribute(self, val=None):
"""Set or return the _my_attribute instance variable."""

if not val is None: self._my_attribute = val return return
self._my_attribute

I'd then have code that would use it, like this:

print "value is: %s" % self.my_attribute()
self.my_attribute("13")
print "value is now: %s" % self.my_attribute()

The obvious problem with the above is that you can't use it to set an
attribute to None. The method itself also reads rather strangely. Is there
a better (concise) way to write it so that you can actually pass in None,
and not set the attribute's value to None inadvertently whenever you try
and access it?

I thought of having get_my_attribute() and set_my_attribute() but I don't
really like the idea because it just makes code that uses them more
(unnecessarily) long winded, and the author of the above URL advises
against it (though they don't say why).

I've not noticed any use of accessor methods in sample Python code
(i.e. in books/tutorials); do people use them much in Python?

Thanks.

--
Graham

Marcin 'Qrczak' Kowalczyk

unread,
Jun 25, 2001, 3:05:53 PM6/25/01
to
Mon, 25 Jun 2001 09:48:23 +0100, Graham Ashton <gra...@coms.com> pisze:

> def my_attribute(self, val=None):

> The obvious problem with the above is that you can't use it to set an
> attribute to None.

The generic solution to such problems is to use the following syntax
instead of default values of parameters:

def my_attribute(self, *args):

Extra arguments are available in the tuple args. A downside is that you
should implement checking for the right number of arguments yourself,
i.e. somebody might call obj.my_attribute(x,y,z) and it's your business
to detect this.

Arbitrary meaning to keyword arguments is specified thus:

def my_attribute(self, *args, **kwargs)

Note that it's impossible to detect the order of keyword arguments...

--
__("< Marcin Kowalczyk * qrc...@knm.org.pl http://qrczak.ids.net.pl/
\__/
^^ SYGNATURA ZASTĘPCZA
QRCZAK

Greg Ewing

unread,
Jun 25, 2001, 11:17:44 PM6/25/01
to
Graham Ashton wrote:
>
> I thought of having get_my_attribute() and set_my_attribute() but I don't
> really like the idea because it just makes code that uses them more
> (unnecessarily) long winded, and the author of the above URL advises
> against it (though they don't say why).

They're talking about Smalltalk, and in that context it
*is* unnecessarily long-winded to include 'get' and 'set'
in the method names. What they do suggest, i.e.

obj attrname
obj attrname: value

works well in Smalltalk, and is a standard idiom used
throughout the Smalltalk system itself, which is probably
why they recommend it.

Note that those are two separate methods, with different
names (the ':' is part of the method name in Smalltalk).
It doesn't imply that translating this idiom to Python
requires using a single method with a variable argument
list.

The convention I would recommend in Python is

obj.attrname()
obj.set_attrname(value)

Since getting attributes tends to be more common than
setting them, this isn't unbearably verbose, and I find
that having 'set' in the setting method's name helps to
make the code read more explicitly.

> I've not noticed any use of accessor methods in sample Python code
> (i.e. in books/tutorials); do people use them much in Python?

I make extensive use of them in the API of my Python GUI
project (http://www.cosc.canterbury.ac.nz/~greg/python_gui/).
I want the API to be as future-proof as possible, so all
publically-visible attributes of my GUI objects are accessed
through methods. I use the convention I recommended above,
plus a couple of others. One is that the constructors of
my objects allow initial values to be given for all its
attributes using keyword arguments, so that e.g.

b = Button(width = 42, height = 17, text = "Boo!")

is equivalent to

b = Button()
b.set_width(42)
b.set_height(17)
b.set_text("Boo!")

My objects also have a set() method which takes keyword
arguments in the same way, so if you want to change a
bunch of attributes you can set them all in one go with
a statement like

b.set(width = 200, text = "Start Spanish Inquisition")

These two things help to cut down a lot on the verbosity
of using set_xxx methods.

I tend not to use accessor methods so much in code which
is internal to an application or library. Whether this is
a good or bad habit is a matter of judgement. It's a
tradeoff between time spent writing and using the accessor
methods, and time spent revising the rest of the code when
the implementation of an attribute changes.

My experience suggests that, for internal code, it's usually
easier not to bother with accessor methods until a clear need
for them arises. But, as they say, your kilometerage may
vary.

--
Greg Ewing, Computer Science Dept, University of Canterbury,
Christchurch, New Zealand
To get my email address, please visit my web page:
http://www.cosc.canterbury.ac.nz/~greg

Roman Suzi

unread,
Jun 26, 2001, 12:58:10 AM6/26/01
to Greg Ewing, pytho...@python.org
On Tue, 26 Jun 2001, Greg Ewing wrote:

>Since getting attributes tends to be more common than
>setting them, this isn't unbearably verbose, and I find
>that having 'set' in the setting method's name helps to
>make the code read more explicitly.
>
>> I've not noticed any use of accessor methods in sample Python code
>> (i.e. in books/tutorials); do people use them much in Python?
>
>I make extensive use of them in the API of my Python GUI
>project (http://www.cosc.canterbury.ac.nz/~greg/python_gui/).
>I want the API to be as future-proof as possible, so all
>publically-visible attributes of my GUI objects are accessed
>through methods. I use the convention I recommended above,
>plus a couple of others. One is that the constructors of
>my objects allow initial values to be given for all its
>attributes using keyword arguments, so that e.g.
>
> b = Button(width = 42, height = 17, text = "Boo!")
>
>is equivalent to
>
> b = Button()
> b.set_width(42)
> b.set_height(17)
> b.set_text("Boo!")

Greg, I am not convinced that set_* methods are good.
In Python standard library (/usr/lib/python2.1/*.py part of it):
set_* is used 54 times in 18 files. WHile there are
~ 343 classes in 101 file.

set_* deviates slightly from being Python idiom.

In Python

[=] ... b.width # is get
b.width = # is set
del b.width # is del

Of course, there is no need to define self.width by hand,
__setattr__ could catch _both_ forms and do set_attr as
well as attr.

>My objects also have a set() method which takes keyword
>arguments in the same way, so if you want to change a
>bunch of attributes you can set them all in one go with
>a statement like
>
> b.set(width = 200, text = "Start Spanish Inquisition")

This is better.
Then no individual set_ are needed, because
they aren't syntactically scalable, while set() is:

b.set(
width = 200,
text = "Start Spanish Inquisition",
)

could be later extended by adding only essentials:

b.set(
width = 200,
height = 40,
text = "Start Spanish Inquisition",
)

(please not ',' after each parameter)

>These two things help to cut down a lot on the verbosity
>of using set_xxx methods.


Sincerely yours, Roman Suzi
--
_/ Russia _/ Karelia _/ Petrozavodsk _/ r...@onego.ru _/
_/ Tuesday, June 26, 2001 _/ Powered by Linux RedHat 6.2 _/
_/ "It is better to be brief than boring." _/


Graham Ashton

unread,
Jun 26, 2001, 5:36:49 AM6/26/01
to
In article <3B37FED8...@cosc.canterbury.ac.nz>, "Greg Ewing"
<gr...@cosc.canterbury.ac.nz> wrote:

> Graham Ashton wrote:
>>
>> I thought of having get_my_attribute() and set_my_attribute() but I
>> don't really like the idea because it just makes code that uses them
>> more (unnecessarily) long winded, and the author of the above URL
>> advises against it (though they don't say why).
>
> They're talking about Smalltalk, and in that context it *is*
> unnecessarily long-winded to include 'get' and 'set' in the method
> names.

I've had some very interesting replies to this thread, thanks to all who
responded. In short, accessor methods don't appear to be all that popular,
and there appear to be some good reasons why not, not least the
__setattr__ and __getattr__ methods. I've just thrown away all my accessor
methods and am going to have to repair rakes of code, but I must admit
that things are looking cleaner already.

> My experience suggests that, for internal code, it's usually easier not
> to bother with accessor methods until a clear need for them arises. But,
> as they say, your kilometerage may vary.

Indeed. It's interesting how learning a new language changes your outlook
on these issues on the fly...

--
Graham

Greg Ewing

unread,
Jun 26, 2001, 8:02:47 PM6/26/01
to r...@onego.ru, pytho...@python.org
Roman Suzi <r...@onego.ru>:

> [=] ... b.width # is get
> b.width = # is set
> del b.width # is del

But currently the only way of customising those incurs
far too much overhead, particularly __setattr__ which
incurs overhead for *every* attribute assignment, not
just the ones you want to trap.

I believe Guido has a scheme afoot to allow get/set
methods to be defined for individual attributes, so
this may change one day.

But even then, I'd be reluctant to use it for everything.
In my GUI library, many of the things I'm using set_xxx
methods for have noticeable side effects, e.g. changing
the size of a widget causes things to move on the
screen. Hiding functionality like that behind what looks
like an ordinary attribute assignment seems like a bad
idea to me.

So, I stand by my opinion that having methods called
set_xxx is quite Pythonic, on the grounds that explicit
is better than implicit.

Greg Ewing, Computer Science Dept, +--------------------------------------+
University of Canterbury, | A citizen of NewZealandCorp, a |
Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. |
gr...@cosc.canterbury.ac.nz +--------------------------------------+

0 new messages