Search code examples
pythonoopdecoratorencapsulationslots

Why can't slots be used alongside decorators to enforce encapsulation in Python?


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?


Solution

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