Encapsulation in Python

Rick Johnson rantingrickjohnson at gmail.com
Thu Mar 10 19:45:54 EST 2016


On Thursday, March 10, 2016 at 9:28:06 AM UTC-6, Ian wrote: 
> 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. :-)

It is a strange irony that you cannot escape the
encapsulating nature of Python modules (since they are
formed by Python from your source files), but Python freely
allows us to ignore encapsulation in our OOP paradigm...
Hmm, sure, many could argue that Python's "mandatory
modules" are simply a result of convenience, they will say:
"Since we have to write code in source files anyway, why not
utilize the "encapsulation of the source file itself to
define module scope?".

I have witnessed the mayhem that occurs when a language does
not mandate module encapsulation (Ruby, i'm looking directly
at you!!!!), and while i agree with the Python designers
that modules must *ALWAYS* be mandatory, i am not convinced
that module space should be so strictly confined to source
files.

Many times, i would have preferred to define my module space
across multiple files, multiple files that could share state
without resorting to the yoga-style "import contortions",
and/or the dreaded "circular import nightmares" that plague
our community today.

In one way, Python got it right by forcing us to encapsulate
our code into modules, however, it failed by not allowing us
to define both the breadth *AND* width of that encapsulation.
Which brings us up against the brutal reality that: Whilst
python's sycophants love to parrot-off about how we are all
"Adults", it's implementation still attempts to treat us
ignorant little children who are incapable of defining our
own module space.

> 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.

But you're ignoring the most important aspect of
getters/setters, and that is, that they expose an interface.
An interface that must be *EXPLICITLY* created. Good
interfaces *NEVER* happen by accident.

> That's a ton of undesirable boilerplate for little real
> benefit.

I understand the aversion to boilerplate, but most languages
have simplified the creation of getters/setters to the point
that your lament is unfounded. And i would argue that the
benefits of creating rigid interfaces is the gift that
keeps on giving.

> 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.

I used properties quite often when i first began writing
Python code. Heck, i thought they were the best thing since
sliced bread. But now, i have come to hate them. I never use
them in any new code, and when i have free time, i strip
them out of old code. When i am forced to use an interface
that was written with properties, i find that learning the
interface is more difficult

  (1) In a dir listing, one cannot determine which symbols
  are properties, which are attributes, and which are
  methods. The beauty of pure OOP encapsulation, is that,
  *EVERY* exposed symbol is a method. In pure OOP, i don't
  have to wonder if i'm calling a function with no
  parameters, or accessing a property, or accessing an
  attribute, no, i'll know that every access is through a
  method, therefore, i will append "()" when i know the
  method takes no arguments. Consistency is very important.
      
  (2) Properties and attributes encourage vague naming
  schemes. When i read code, i find the code more
  comprehensible when the symbols give me clues as to what
  is going on. So if i read code like: `re.groups`,
  befuddlement sets in. What is "groups"? A function
  object? An attribute? "getCapturingGroupCount" would be a
  better name (but that's semantics) In pure OOP,  methods
  are the only communication meduim, so we're more likely to
  write "getBlah" and "setBlah", and use verbs for
  procedural names -- these naming conventions are more
  comprehensible to the user.
    
  (3) Not all authors correctly utilize leading underscores
  to differentiate between public and private attributes.
  
> 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.

That's a ridiculous statement Ian.




More information about the Python-list mailing list