3

I am trying to change a public to private parameter inside a Python class. As far as I know, to make it private I need to declare for instance:

self.__top = None # <-- Instead of self.top = None

However, I cannot figure out how to make a private struct with private properties, such that they are called properly in the public methods.

For instance:

class Stack:

    def __init__(self, size=None):
        self.__top = None
        if size is None:  # if size is unset
            self.__size = -1
        else:
            self.__size = size
        self.__current_size = -1

    def push(self, data):
        if self.current_size >= self.size: # ERROR!
            print("Stack Overflow!")
            return
2
  • 1
    If you create an attribute self.__size, then it is self.__size, not self.size. The underscores are part of the name.
    – khelwood
    Commented Apr 4, 2019 at 21:55
  • 1
    Python does not have private attributes. You are using double-underscore name-mangling, which is not the same thing as private. By convention, members that are not part of the public api are prepended with a single underscore. This is merely a naming convention. Double-underscore name-mangling is to prevent name-collisions in subclasses. Commented Apr 4, 2019 at 21:59

1 Answer 1

5

I'm assuming that by using terms such as struct, public and private you must come from a background of C/C++. There are no such things in Python, and the naming of the attributes are purely conventional.

I recommend reading What is the meaning of a single and a double underscore before an object name?.

Typically for your "private" attributes which you don't want for others to use outside of your class, the convention is to prefix it with a single underscore _, like _size. If you plan on using this outside, it boils down to these cases:

  • do you want it to be writable from outside? In that case you just define it as size and use it like this everywhere
  • do you want it to be read-only from outside? In this case you can make it private and make a property for it like:

Code:

class A:

    self __init__(self, size):
        self._size = size

    @property
    def size(self):
        return self._size

You also have the ability to translate the internal variable to another name, and make it writable at the same time under that different name.

Example:

class A:

    def __init__(self, value):
        self._internal_var = value

    def set_data(self, value):
        self._internal_var = value

    def get_data(self):
        return self._internal_var

    data = property(get_data, set_data)

Or alternatively:

@property
def data(self):
    return self._internal_var

@data.setter
def data(self, value):
    self._internal_var = value

Then if you call

a1 = A(11)
print(a1.data)
a1.data = 22
print(a1.data)

it will yield:

11
22

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.