0

I've read that there is no strict enforcement of Encapsulation in Python. slots is generally used for purposes of faster attribute access and memory savings as reflected in here. However can encapsulation be enforced strictly with the usage of slots and decorators as shown in the following code:

class GetSet(object):

__slots__ = ["attrval"]
def __init__(self,value):
    self.attrval = value

@property
def var(self):
    #print 'getting the "var" attribute'
    return self.attrval

@var.setter
def var(self,value):
    #print 'setting the "var" attribute'
    self.attrval = value

@var.deleter
def var(self):
    #print 'deleting the "var" attribute'
    self.attrval = None

An instance of GetSet won't have dynamic variable setting(due to slots) and also the setter and getter methods would invoke the method definitions in the class. Isn't encapsulation invoked entirely?

1 Answers1

0

I've read that there is no strict enforcement of Encapsulation in Python.

Because attributes are public always. And they can be reached no matter what you do, even if you use __ member prefix:

class GetSet(object):

    __slots__ = ["__attrval"]
    def __init__(self,value):
        self.__attrval = value

    @property
    def var(self):
        print 'getting the "var" attribute'
        return self.__attrval

    @var.setter
    def var(self,value):
        print 'setting the "var" attribute'
        self.__attrval = value

    @var.deleter
    def var(self):
        #print 'deleting the "var" attribute'
        self.__attrval = None

obj = GetSet(100)
# print obj.__attrval # error
# obj.__attrval = 200 # error
print obj._GetSet__attrval # got it.

You just encapsulate by convention, you use single _ to signal your library code users that's a private member and they respect you, because otherwise their client-code can face consequences in the future.

Properties are convenient because they allow you to avoid completely getters and setters. If you need them later you can add a property.

progmatico
  • 4,714
  • 1
  • 16
  • 27
  • Could you explain how you came up with `print obj._GetSet__attrval`, also what did you mean by "Properties are convenient because they allow you to avoid completely getters and setters. If you need them later you can add a property." Also, is there anyway to bypass slots for dynamically initializing attributes.Thanks a lot for the answer. – P. Sai Prasanth Oct 25 '18 at 14:24
  • It's called name mangling. Please read section [9.6 Private Variables](https://docs.python.org/3/tutorial/classes.html?highlight=mangling) – progmatico Oct 25 '18 at 18:54
  • 1
    @P.SaiPrasanth: for the remaining, I mean in Python you usually add members to class that you know are public, but you don't care. If latter you need to make members read-only, or member validation, or access interception you change the member name to `_membername` to make clear it should not be accessed from outside, and then you use the property decorator to add a property named `membername`. The client code still works with no changes and you get "getter/setter" functionality behing the scenes. – progmatico Oct 25 '18 at 19:01