views:

104

answers:

4

Hi,

I have been trying to use properties instead of specific setters and getters in my app. They seem more pythonic and generally make my code more readable.

More readable except for one issue: Typos.

consider the following simple example (note, my properties actually do some processing even though the examples here just set or return a simple variable)

class GotNoClass(object):

    def __init__(self):
        object.__init__(self)
        self.__a = None

    def __set_a(self, a):
        self.__a = a

    def __get_a(self):
        return self.__a

    paramName = property(__get_a, __set_a)


if __name__ == "__main__":
    classy = GotNoClass()

    classy.paramName = 100
    print classy.paramName

    classy.paranName = 200
    print classy.paramName

    #oops! Typo above! as seen by this line:
    print classy.paranName

The output, as anyone who reads a little closely will see, is:

100
100
200

Oops. Shouldn't have been except for the fact that I made a typo - I wrote paranName (two n's) instead of paramName.

This is easy to debug in this simple example, but it has been hurting me in my larger project. Since python happily creates a new variable when I accidentally meant to use a property, I get subtle errors in my code. Errors that I am finding hard to track down at times. Even worse, I once used the same typo twice (once as I was setting and later once as I was getting) so my code appeared to be working but much later, when a different branch of code finally tried to access this property (correctly) I got the wrong value - but it took me several days before I realized that my results were just a bit off.

Now that I know that this is an issue, I am spending more time closely reading my code, but ideally I would have a way to catch this situation automatically - if I miss just one I can introduce an error that does not show up until a fair bit of time has passed...

So I am wondering, should I just switch to using good old setters and getters? Or is there some neat way to avoid this situation? Do people just rely on themselves to catch these errors manually? Alas I am not a professional programmer, just someone trying to get some stuff done here at work and I don't really know the best way to approach this.

Thanks.

P.S. I understand that this is also one of the benefits of Python and I am not complaining about that. Just wondering whether I would be better off using explicit setters and getters.

+2  A: 

Have you tried a static analysis tool? Here is a great thread about them.

Tamás Szelei
+1  A: 

If properties are bugging you (pun intended), then by all means go back to getters and setters. Maybe you'd want to reserve properties for read-only attributes, they don't seem to do much harm there and they may catch bugs where attributes are accidentally overwritten.

I didn't even know about properties until recently, and it seems I'm not the only one. Lots of Python programmers get by without them. In fact, not using properties can be considered more pythonic because explicit is better than implicit.

larsmans
+1 for the read-only attributes. I generally use properties only for those.
Space_C0wb0y
Will the person who down-voted this post please explain why?
larsmans
I agree with you. I will be moving back to setters and getters and love every minute of it :)
Ben
A: 

There are times when compile-time checking really saves time. You seem to have identified one such case. By accident rather than careful choice I use getters and setters, and am happy ;-)

djna
+2  A: 

Depending on how your code works, you could try using slots. You'll get an AttributeError exception thrown when you try to assign something that's not in slots then, which will make such typo's more obvious.

Wow. Slots are very very interesting (and new to me). I will definitely be implementing them as part of my app, but not to solve this issue. For this it seems as though it might be an abuse of their intended purpose (which, I gather, is to reduce memory footprints of objects that are likely to be instanced very many times). One thing I am considering, though, is to temporarily use them during development and then shut them off once I have completed my code - that way they will keep me honest now but not actually be in use (or abuse?) once my app is complete.
Ben
On second thought, looking at some of the unintended consequences of using __slots__, I won't be implementing them even during development. Still very cool to learn about though.
Ben