I understand that in Python there is no real notion of private/protected/public class members. Yet, using underscores this can be achieved to some extents. For example, consider an object that is supposed to count the number of even integers on a stream. The following would be a relatively safe implementation
class EvensCounter:
def __init__(self):
self._count = 0
def __call__(self, n):
if n % 2 == 0:
self._count += 1
@property
def count(self):
return self._count
This way, the user cannot accidentally change count for example in the following way:
counter = EvensCounter()
counter.count = 5 # Gives AttributeError: can't set attribute
I used to see this as an equivalent of defining count as a private member variable in C++ and then having only a getter that returns a const reference to the private member variable.
However, I realize that the above is not exactly correct. Suppose instead of a simple int, count was of a more sophisticated type of MyInt defined as follows:
class MyInt:
def __init__(self):
self._value = 0
def inc(self, n=1):
self._value += n
@property
def value(self):
return self._value
class EvensCounter:
def __init__(self):
self._count = MyInt()
def __call__(self, n):
if n % 2 == 0:
self._count.inc()
@property
def count(self):
return self._count
In this case, the following piece of code would work and effectively modify the count value:
counter = EvensCounter()
counter.count.inc(5)
While the user cannot change _count variable to reference another object, it can still call methods of that object that change its state. (Whereas in C++, because the inc() method is not a const method, it cannot be called on a const reference.)
I was wondering if there is a mechanism in Python that provides same safety guarantees as the const references of C++? Namely, I need a way to expose a reference to a (private) member of the class that only allows the user to 'read' that member variable, but does not permit him to change the state of that member variable.
No comments:
Post a Comment