Encapsulation in Python

Ian Kelly ian.g.kelly at gmail.com
Thu Mar 10 10:27:09 EST 2016


On Thu, Mar 10, 2016 at 6:41 AM, Ben Mezger <me at benmezger.nl> wrote:
> Hi all,
>
> I've been studying Object Oriented Theory using Java. Theoretically, all
> attributes should be private, meaning no one except the methods itself
> can access the attribute;
>
> public class Foo {
>     private int bar;
>     ...

Encapsulation in Python is based on trust rather than the
authoritarian style of C++ / Java. The maxim in the Python community
is that "we're all consenting adults". If I don't intend an attribute
to be messed with, then I'll mark it with a leading underscore. If you
mess with it anyway, and later your code breaks as a result of it,
that's your problem, not mine. :-)

> Normally in Java, we would write getters and setters to set/get the
> attribute bar. However, in Python, we normally create a class like so;
>
> class Foo(object):
>     bar = 0
>     ...
>
> And we usually don't write any getters/setters (though they exist in
> Python, I have not seen much projects making use of it).

The vast majority of getters and setters do nothing other than get/set
the field they belong to. They exist only to allow the *possibility*
of doing something else at some point far in the future. That's a ton
of undesirable boilerplate for little real benefit.

In Python, OO designers are able to get away with not using getters
and setters because we have properties. You can start with an
attribute, and if you later want to change the means of getting and
setting it, you just replace it with a property. The property lets you
add any logic you want, and as far as the outside world is concerned,
it still just looks like an attribute.

> We can easily encapsulate (data hiding) Foo's class using the '_'
> (underscore) when creating a new attribute, however, this would require
> all attributes to have a underscore.

A single leading underscore is just a naming convention, not true data
hiding, which isn't really possible in Python. Even the double
underscore only does name mangling, not true data hiding. It's meant
to prevent *accidental* naming collisions. You can still easily access
the attribute from outside the class if you're determined to.

This all boils down to the fact that code inside a method has no
special privilege over external code. If you could hide data so well
that external code really couldn't access it, then you wouldn't be
able to access it either.



More information about the Python-list mailing list