0

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
Akash Pagar
  • 637
  • 8
  • 22
  • Just change it to `self.__arr`, just like the other private attributes. Why do you think it would be different? – Barmar May 11 '20 at 12:21
  • Don't try enforce that. It only works by convention: name your list `_arr` - with one leading underscore to let everyone know that this is for internal use only and not supposed to be manipulated. See https://stackoverflow.com/questions/1301346/what-is-the-meaning-of-a-single-and-a-double-underscore-before-an-object-name for the reasons of using double underscores. – Thierry Lathuille May 11 '20 at 12:24

1 Answers1

1

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=', ')
Barmar
  • 741,623
  • 53
  • 500
  • 612