Matthias Kaeppler wrote: > Why would I want to use an attribute in Python, where I would use > getters and setters in Java? 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...), but is that a reason to only write white box classes? ^^ > > - Matthias >
If you've ever written non-trivial code in Java, you can't deny that most of the classes are littered by pages and pages of -- protected FooClass foo; FooClass getFoo() { return foo; } void setFoo(FooClass foo) { this.foo = foo; } -- This is more or less equivalent to a simple -- public FooClass foo; -- but allows you to change the implementation details of the class without having to bork your whole interface later. Now, you have no reason to do this in python, you can use a regular "real" attribute, and if you need to change the implementation details, you can remove the real attribute and replace it with a virtual attribute through properties without changing the class' interface. -- >>> class Bar(object): def __init__(self): self.foo = 5 >>> bar = Bar() >>> bar.foo 5 >>> >>> # now let's change the Bar class implementation and split foo in boo and far >>> >>> class Bar(object): def __init__(self): self.boo = 2 self.far = 3 def _getfoo(self): return self.boo + self.far foo = property(_getfoo) >>> bar = Bar() >>> bar.foo 5 -- And this is completely transparent for anyone using the Bar class, they don't give a damn about what happens inside. You can also use it to add checks on the allowed values, for example -- >>> class Bar(object): def __init__(self): self._foo = 5 def _getfoo(self): return self._foo def _setfoo(self,foo): if not 0 <= foo <= 10: raise ValueError("foo's value must be between 0 and 10 (included)") self._foo = foo foo = property(_getfoo, _setfoo) >>> bar = Bar() >>> bar.foo 5 >>> bar.foo = 2 >>> bar.foo 2 >>> bar.foo = 20 Traceback (most recent call last): File "<pyshell#42>", line 1, in -toplevel- bar.foo = 20 File "<pyshell#37>", line 8, in _setfoo raise ValueError("foo's value must be between 0 and 10 (included)") ValueError: foo's value must be between 0 and 10 (included) >>> -- or everything else you'd use Java's getters/setters for, but without having to over-engineer your classes and wrap everything just because the language doesn't allow you to change your mind if you ever realize you made mistakes in the previous implementations. -- http://mail.python.org/mailman/listinfo/python-list