On Sun, 11 Dec 2005 17:05:16 +0100, Matthias Kaeppler wrote: > Why would I want to use an attribute in Python, where I would use > getters and setters in Java?
Oh boy! I've just come out of a rather long thread about that very issue. If you care enough to read a bunch of people arguing past each other, check the thread "Another newbie question", especially the posts about the so-called Law of Demeter. But for the short summary: suppose I write a class: class Parrot: def __init__(self, x): self._x = x print "please use instance.getx() and setx()" def getx(self): return self._x def setx(self, x): self._x = x What if I want to export methods of x other than get and set? Perhaps x is a numeric value: now I have to export a whole series of arithmetic operators: addx, subx, mulx, etc. And there may be other attributes I need to export as well... When I write getter and setter methods for an attribute, I make myself responsible for maintaining everything about that attribute. I create extra functions that need to be tested, debugged and documented. I expect my class users to learn how to use my class, and every method is another method they have to learn about. Writing getter and setter methods have costs -- I pay some of those costs, and my users pay some of those costs. Then I get fed up and write this class instead: class NorwegianBlue: def __init__(self, x): self.x = x print "please use public attribute instance.x" NorwegianBlue is a much smaller class. That means less development time for me, less test code to write, less documentation, less time needed for my users to learn the API -- they already know what the API for x is, because they supplied it. The costs to both class designer and class user are much less, the flexibility is greater, and I finish writing the class quicker. Is there a disadvantage to NorwegianBlue? Yes -- I am now locked in to one particular interface. I can't even do something as trivial as change the name of attribute x. But then I can't change the name of Parrot.getx either, not without breaking people's code. But still, sometimes I know that I will want to -- or even that I might want to -- radically change the implementation of my class. Perhaps x is a list now, but later it will be a binary tree. How much effort will be needed to fix the breakage if NorwegianBlue changes? If the expected effort to fix the breakage is more than the effort to write setters and getters, then it makes sense to write setters and getters. But contrariwise, if it will take less effort to fix the problem than to defend against it, then why defend against it? Getters and setters are insurance against you changing the private interface. You wouldn't pay $20,000 a year to protect a $20,000 car. You might not even pay $1,000 a year. So do your trade-offs, and make your decision. > I know that encapsulation is actually just > a hack in Python (common, "hiding" an implementation detail by prefixing > it with the classname so you can't access it by its name anymore? Gimme > a break...), I'll give you a much better break in C++: #def private = public So much for encapsulation, hey? Java makes it harder, but not that much more: http://www.informit.com/articles/article.asp?p=174217&seqNum=3&rl=1 > but is that a reason to only write white box classes? ^^ Why would you want to write black box classes? Python is not a bondage and discipline language. Remember kids, whips and chains are only for mummies and daddies who love each other very much. Python includes tools for preventing people *accidentally* shooting themselves in the foot. But the philosophy of the language is to allow, even to encourage, people to tinker under the hood. If that means that somebody *deliberately* shoots themselves in the foot, well, that's the price you pay for freedom: some people make stupid decisions. I look at it this way: as the class designer, I have ZERO idea what attributes and methods of my class will be just the perfect thing to solve somebody's problem, so it is rude of me to lock them up as private -- especially since they *will* find a way to hack my class and access my private attributes and methods anyway. All I'm doing is making their life miserable by making them go out and buy books like "Hacking Private Attributes In Java" or something. But as a class designer, I know perfectly well which of my class members are free for anyone to touch (instance.public), which should be considered private by convention (instance._private) and which need a great big sign on the door saying "Enter At Own Risk! Don't touch this unless you know what you are doing!!!" (instance.__mangled). -- Steven. -- http://mail.python.org/mailman/listinfo/python-list