Search code examples
pythonalgorithmdata-structuresstackencapsulation

How to implement Stack using Python encapsulation?


I have implemented Stack data structure in python, where maxsize, top, and arr these are the instance variables in Stack class. The maxsize and top variables are getting changed by setter method. As in C++ or Java when we define stack or queue we have some private variables which we do not want to get directly accessed outside class and values should not change. The variables top and maxsize I have managed to behave like private by writing getters and setters in class.

How can I achieve same thing in Python that the instance variable arr which holding stack elements cannot be changed outside the class using object.

Is there any way to make arr variable as private? or the some other native data type need to used for Stack implementation in Python?

Stack implementation:

class Stack:
    def __init__(self, maxsize):
        self.maxsize = maxsize
        self.top = -1
        self.arr = []

    @property
    def maxsize(self):
        return self.__maxsize

    @maxsize.setter
    def maxsize(self, maxsize):
        if maxsize < 1:
            maxsize = 1
        if not getattr(self, 'maxsize', None):
            self.__maxsize = maxsize

    @property
    def top(self):
        return self.__top

    @top.setter
    def top(self, top):
        if getattr(self, 'top', -1) < self.maxsize and top < self.maxsize and top >= -1:
            if abs(getattr(self, 'top', -1) - top) in (0, 1):
                self.__top = top

    def is_empty(self):
        return self.top == -1

    def is_full(self):
        return self.top == self.maxsize - 1

    def push(self, ele):
        if self.is_full():
            return
        self.top += 1
        self.arr.append(ele)
        return ele

    def pop(self):
        if self.is_empty():
            return
        ele = self.arr[self.top]
        del self.arr[self.top]
        self.top -= 1
        return ele

    def display(self):
        print(*self.arr, sep=', ')


s = Stack(10)

s.push(23)
s.push(45)
s.push(34)

print("before changing arr >>>>> ")
s.display()
s.arr = [3,3,3,3,3,3,3,3] # this line breaking the stack implementation
                          # either it should raise error or should not change the
                          # value of variable which holding stack elements
print("after changing arr >>>>> ")
s.display()

Output:

before changing arr >>>>> 
23, 45, 34
after changing arr >>>>> 
3, 3, 3, 3, 3, 3, 3, 3

Solution

  • Change self.arr to self.__arr everywhere in the class. You don't need to create a setter or getter, since you don't want to expose this outside the class.

    class Stack:
        def __init__(self, maxsize):
            self.maxsize = maxsize
            self.top = -1
            self.__arr = []
    
        @property
        def maxsize(self):
            return self.__maxsize
    
        @maxsize.setter
        def maxsize(self, maxsize):
            if maxsize < 1:
                maxsize = 1
            if not getattr(self, 'maxsize', None):
                self.__maxsize = maxsize
    
        @property
        def top(self):
            return self.__top
    
        @top.setter
        def top(self, top):
            if getattr(self, 'top', -1) < self.maxsize and top < self.maxsize and top >= -1:
                if abs(getattr(self, 'top', -1) - top) in (0, 1):
                    self.__top = top
    
        def is_empty(self):
            return self.top == -1
    
        def is_full(self):
            return self.top == self.maxsize - 1
    
        def push(self, ele):
            if self.is_full():
                return
            self.top += 1
            self.__arr.append(ele)
            return ele
    
        def pop(self):
            if self.is_empty():
                return
            ele = self.__arr[self.top]
            del self.__arr[self.top]
            self.top -= 1
            return ele
    
        def display(self):
            print(*self.__arr, sep=', ')