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