OO in Python? ^^
Bruno Desthuilliers
bdesth.quelquechose at free.quelquepart.fr
Sun Dec 11 16:45:21 EST 2005
Matthias Kaeppler a écrit :
(snip)
> I stumbled over this paragraph in "Python is not Java", can anyone
> elaborate on it:
>
> "In Java, you have to use getters and setters because using public
> fields gives you no opportunity to go back and change your mind later to
> using getters and setters. So in Java, you might as well get the chore
> out of the way up front. In Python, this is silly, because you can start
> with a normal attribute and change your mind at any time, without
> affecting any clients of the class. So, don't write getters and setters."
>
> Why would I want to use an attribute in Python, where I would use
> getters and setters in Java?
Because you don't *need* getters/setters - you already got'em for free
(more on this latter).
> 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...),
You're confusing encapsulation with information hiding. The mechanism
you're refering to is not meant to 'hide' anything, only to prevent
accidental shadowing of some attributes. The common idiom for
"information hiding" in Python is to prefix 'protected' attributes with
a single underscore. This warns developers using your code that this is
implementation detail, and that there on their own if they start messing
with it. And - as incredible as this can be - that's enough.
True, this won't stop stupid programmers from doing stupid thing - but
no language is 'idiot-proof' anyway (know the old '#define private
public' C++ trick ?), so why worry ?
> but is that a reason to only write white box classes? ^^
First, what is a 'white box' class ?
public class WhiteBox {
protected integer foo;
protected integer bar;
public integer getFoo() {
return foo;
}
public void setFoo(integer newfoo) {
foo = newfoo;
}
public integer getBar() {
return bar;
}
public void setBar(integer newbar) {
bar = newbar;
}
}
Does this really qualify as a 'blackbox' ? Of course not, everything is
publicly exposed. You could have the exact same result (and much less
code) with public attributes.
Now what is the reason to write getters and setters ? Answer : so you
can change the implementation without breaking the API, right ?
Python has something named 'descriptors'. This is a mechanism that is
used for attribute lookup (notice that everything being an object,
methods are attributes too). You don't usually need to worry about it
(you should read about if you really want to understand Python's object
model), but you can still use it when you need to take control over
attribute access. One of the simplest application is 'properties' (aka
computed attributes), and here's an exemple :
class Foo(object):
def __init__(self, bar, baaz):
self.bar = bar
self._baaz = baaz
def _getbaaz(self):
return self._baaz
baaz = Property(fget=_getbaaz)
This is why you don't need explicit getters/setters in Python : they're
already there ! And you can of course change how they are implemented
without breaking the interface. Now *this* is encapsulation - and it
doesn't need much information hiding...
More information about the Python-list
mailing list