Encapsulation unpythonic?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sun Sep 1 22:57:37 EDT 2013


On Sun, 01 Sep 2013 20:59:25 -0400, Roy Smith wrote:

> In article <mailman.468.1378083075.19984.python-list at python.org>,
>  Ethan Furman <ethan at stoneleaf.us> wrote:
> 
>> On 09/01/2013 02:54 PM, Tim Delaney wrote:
>> > Roy Smith wrote:
>> >>
>> >> Nothing is accessible in Python except via getters and setters.  The
>> >> only difference between Python and, say, C++ in this regard is that
>> >> the Python compiler writes them for you most of the time and doesn't
>> >> make you put ()'s at the end of the name
>> >
>> > I think Roy is referring to the fact that attribute access is
>> > implemented via __getattr__ / __getattribute__ /
>> > __setattr__ / __delattr__. From one point of view, he's absolutely
>> > correct - nearly all attributes are accessed via getters/setters in
>> > Python.
>> 
>> Seems to me there is a difference between an underlying generic
>> protocol for data manipulation and "Python writing them
>> [getters/setters] for you".
> 
> Why?  When I write "foo.bar", a bunch of generic code gets run which
> figures out what value to return.  If I don't like the generic behavior,
> I can write my own __getattrr__(), etc, and make it do whatever I want.
> 
> How is that any different from, in C++, if you don't write a default
> constructor, the compiler will write one for you.  If you don't like the
> generic behavior you get from that, you can write your own and make it
> do whatever you want.


And fundamentally, all programming is flipping bits, therefore all 
languages are exactly the same, right? :-)


I can't speak for C++, but comparing Java and Python there are 
differences:


- Java the language makes it a pain to change your mind and convert a 
public attribute to a computed attribute. Since the pain of changing your 
mind far outweighs the pain of writing trivial getters/setters up front, 
it is good defensive practice to make attribute access via getters just 
in case. Python makes it trivial to change your mind, and so YAGNI rules 
and you shouldn't write getters unless you actually need them.

- Perhaps because the focus in Java is on massive projects with large 
numbers of barely adequate coders, Java tries to protect the average 
coder from shooting themselves in the foot. Consequently, Java encourages 
a philosophy of "default deny" when it comes to attribute access: don't 
give your caller access to anything except the absolute minimum you know 
they need. In Python, the focus tends to be more about smaller projects 
with small teams of better than average coders, and a philosophy of 
"we're all adults here". Consequently, Python code tends towards 
"everything not explicitly prohibited is permitted".

- Similarly, while Java the language doesn't force you to *explicitly* 
declare members as public (if you don't declare members private, they are 
public), it strongly encourages you to think about information hiding and 
explicitly mark members as public. Python does not. There is no way to 
explicitly mark attributes as public.

- The Java compiler enforces public/private, while Python treats it as a 
convention. (At least for pure-Python code.)


But notice that they are differences of degree, not kind. Java encourages 
information hiding in classes, but does not prohibit you from making 
members public, and using reflection you can break into classes and get 
access to anything; Python allows information hiding, but trusts the 
programmer to honour "private" names, and reflection is such a 
fundamental part of Python that we don't even call it that.


-- 
Steven



More information about the Python-list mailing list