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