Although there are not direct "private" variable conventions in python, you can certainly implement your own to varying degrees. In addition to prepended underscore or getter/setter methods, you can implement a truly private variable using Cython.
Create the following files PriVar.pyx and setup.py with the follow contents respectively
# PriVar.pyx
cdef class PrivateVariable:
cdef int _value
def __cinit__(self):
self._value = 0
def getvalue(self):
return self._value
def setvalue(self, value):
self._value = value
# setup.py
from setuptools import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize('PriVar.pyx'))
Now build the module with the following command
python3.10 setup.py build_ext --inplace
Now you can simulate "private" variables that are only accessible via the getter/setter functions.
Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from PriVar import PrivateVariable
>>> myvar = PrivateVariable()
>>> dir(myvar)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', 'getvalue', 'setvalue']
# try to get __dict__
>>> myvar.__dict__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'PriVar.PrivateVariable' object has no attribute '__dict__'. Did you mean: '__dir__'?
# can get and set, but not see
>>> myvar.getvalue()
0
>>> myvar.setvalue(42)
>>> myvar.getvalue()
42
>>> myvar.value
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'PriVar.PrivateVariable' object has no attribute 'value'
# hmmm maybe its hidden?
>>> myvar._value
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'PriVar.PrivateVariable' object has no attribute '_value'
>>> myvar.__value
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'PriVar.PrivateVariable' object has no attribute '__value'. Did you mean: 'getvalue'?
# definitely can not set a non existent attribute
>>> myvar.value = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'PriVar.PrivateVariable' object has no attribute 'value'
# lets try and override it with subclassing
>>> class NewPrivateVariable(PrivateVariable):
... def __init__(self, v):
... self.value = v
...
>>> mynewvar = NewPrivateVariable(100)
>>> mynewvar.value
100
>>> mynewvar.__dict__
{'value': 100}
>>> mynewvar.getvalue()
0
>>> mynewvar.setvalue(5)
>>> mynewvar.getvalue()
5
# still can not access value associated with getter/setter function.. it's private!!
*edit the reason this works is Cython cdef int "variable" is created as private to the Cython modules scope. You can set public and readonly attributes as well. https://cython.readthedocs.io/en/latest/src/userguide/extension_types.html#static-attributes