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. -- https://mail.python.org/mailman/listinfo/python-list