1

I was doing some research about the use of encapsulation in object oriented programming using Python and I have stumbled with this topic that has mixed opinions about how encapsulated attributes work and about the usage of them. I have programmed this piece of code that only made matters more confuse to me:

class Dog:
    def __init__(self,weight):
        self.weight = weight
        __color =''
    def set_color(self,color):
        self.__color = color
    def get_color(self):
        print(self.__color)
rex = Dog(59)
rex.set_color('Black')
rex.get_color()
rex.color = 'White'
rex.__color = rex.color
print(rex.__color)
rex.get_color()

The result is:

>Black
>White
>Black

I understand that the reason behind this is because when we do the assignment rex.__color = rex.color, a new attribute is created that does not point to the real __color of the instanced Dog. My questions here are:

  • Is this a common scenario to occur?
  • Are private attributes a thing used really often?
glibdud
  • 7,550
  • 4
  • 27
  • 37
Arthur LC
  • 23
  • 4

2 Answers2

1

In a language that does not have properties (eg. java) this is so common that it has become a standard, and all frameworks assume that getters/setters already exist.

However, in python you can have properties, which are essentially getters/setters that can be added later without altering the code that uses the variables. So, no reason to do it in python. Use the fields as public, and add properties if something changes later.

Note: use single instead of double underscore in your "private" variables. Not only it's the common convention, but also, double underscore is handled differently by the interpreter.

blue_note
  • 27,712
  • 9
  • 72
  • 90
  • Thank you for your answer, this direct translation from Java to Python is exactly what I want to avoid. – Arthur LC Oct 02 '18 at 11:37
  • @ArthurLC: ok, properties allow you to still write `object.x = 5`, but instead of setting `x`, this calls the `set_x` method without the user changing anything or even knowing. In java you can't do that, so you add getters/setters *just in case* something changes (in most cases they are totally useless) – blue_note Oct 02 '18 at 11:40
  • @ArthurLC: also, note that the usual java getters/setters *are not* encapsulation, as they are not actually hiding anything (you could directly use the variable as well) – blue_note Oct 02 '18 at 11:41
0

Encapsulation is not about data hidding but about keeping state and behaviour together. Data hidding is meant as a way to enforce encapsulation by preventing direct access to internal state, so the client code must use (public) methods instead. The main points here are 1/ to allow the object to maintain a coherent state (check the values, eventually update some other part of the state accordingly etc) and 2/ to allow implementation changes (internal state / private methods) without breaking the client code.

Languages like Java have no support for computed attributes, so the only way to maintain encapsulation in such languages is to make all attributes protected or private and to eventally provide accessors. Alas, some people never got the "eventually" part right and insist on providing read/write accessors for all attributes, which is a complete nonsense.

Python has a strong support for computed attributes thru the descriptor protocol (mostly known via the generic property type but you can of course write your own desciptors instead), so there's no need for explicit getters/setters - if your design dictates that some class should provide a publicly accessible attribute as part of it's API, you can always start with just a public attribute and if at some point you need to change implementation you can just replace it with a computed attribute.

This doesn't mean you should make all your attributes public !!! - most of the time, you will have "implementation attributes" (attributes that support the internal state but are in no way part of the class API), and you definitly want to keep those protected (by prefixing them with a single leading underscore).

Note that Python doesn't try to technically enforce privacy, it's only a naming convention and you can't prevent client code to access internal state. Nothing to be worried about here, very few peoples stupid enough to bypass the official API without good reasons, and then they know their code might break something and assume all consequences.

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118