Read-only attributes

by gldnspud on November 2, 2007

I just found an interesting pattern while writing a class where I wanted to expose an attribute publicly, but in a read-only manner.

Here's the skeleton version of the code:

from operator import attrgetter

class Connection(object):

    def __init__(self, uri):
        self._uri = uri

    uri = property(attrgetter('_uri'))

Ever since discovering operator, in particular attrgetter, I've been finding more useful places to use it. It makes me feel naive now to think that I would once write the above like this:

class Connection(object):

    def __init__(self, uri):
        self._uri = uri

    @property
    def uri(self):
        return self._uri

For me, the first example is more meaningful at a glance.

{ 5 comments }

Roberto November 2, 2007 at 2:12 pm

Beautiful! :)

Alexander Botero-Lowry November 2, 2007 at 5:08 pm

Very neat! I’ve always done:

uri = property(lambda x: x._url)

which though terse isn’t as clear as attrgetter!

Frank Benkstein November 2, 2007 at 11:24 pm

Why not simply use property(lambda self: self._uri)?

Wyatt November 10, 2007 at 10:55 am

Just for fun, how about this:

uri = property(lambda self: self._uri)

gldnspud November 17, 2007 at 6:59 pm

@Frank, @Wyatt: Mostly because I’ve been trained, from the people and code I’ve worked with, to avoid lambdas 99% of the time, giving preference to named function definitions. So, what I used to use was:

@property
def abc(self):
    return self._abc

Using attrgetter makes it easy to turn that into a one-liner, without having to use lambda :) Plus, as Alexander points out, the name “attrgetter” certainly tells you pretty directly what’s going on.

Comments on this entry are closed.

Previous post:

Next post: