True private attributes in Python
Some background - Private attributes in a class
In many programming languages there is support for making variables private to
prevent unintended consequences. But in Python there is no direct support for
it in class
definitions. All attributes of an object in Python are available
publicly. For better understanding lets take an example.
import pprint class SomeClass: def __init__(self, a): self.a = a # Meant for public use self._b = "Private but is directly available for public use" self.__c = "Private but name is changed for public use" def __test(self): return self._b pprint.pprint(dir(SomeClass(2)))
Which produces the following output:
['_SomeClass__c', '_SomeClass__test', ..., '_b', 'a']
These are all the attributes that we can use on an object of SomeClass
. So,
all of the following will work:
obj = SomeClass()
obj._SomeClass__c
obj._SomeClass__test()
obj._b
obj.a
What we realize here is that the value of obj._SomeClass__c
is the same as the
value of private variable __c
. What we instead want is deny public access to
__c
but that isn’t straight forward. A well motivated user of the class would
be able to use the private attributes without much issue.
This is where local variables and local functions come into play.
The solution - Using local variables in local functions
Functions are a great way to make the code more modular and we can even treat them as objects. Lets see how we define a class and a function with private variables and methods.
from typing import Callable from dataclasses import dataclass @dataclass(slots=True) # Restricts creating new attributes class SomeClass: x: int y: int func: Callable[[], int] def create_SomeClass(x, y): k = x / y # Private variable def private_func(z): # Can't be accessed outside create_SomeClass return k - z def public_func(): return x + private_func(y * 2) return SomeClass(x=x, y=y, func=public_func) obj = create_SomeClass(2, 5) print(obj.func())
-7.6