What would be the most convenient way to create a class which instances’ attributes can’t be changed from outside the class (you could still get the value), so it’d be possible to call self.var = v inside the class’ methods, but not ClassObject().var = v outside of the class?
I’ve tried messing with __setattr__() but if I override it, the name attribute cannot be initiated in the __init__() method. Only way would be to override __setattr__() and use object.__setattr__(), which I am doing at the moment:
class MyClass(object):
def __init__(self, name):
object.__setattr__(self, "name", name)
def my_method(self):
object.__setattr__(self, "name", self.name + "+")
def __setattr__(self, attr, value):
raise Exception("Usage restricted")
Now this solution works, and it’s enough, but I was wondering if there’s even a better solution. The problem with this one is: I can still call object.__setattr__(MyClass("foo"), "name", "foo_name") from anywhere outside the class.
Is there any way to totally prevent setting the variable to anything from outside of the class?
EDIT: Stupid me not mentioning I’m not looking for property here, some of you already answered it, however it’s not enough for me since it will leave self._name changeable.
No, you cannot do this in pure python.
You can use properties to mark your attributes as read-only though; using underscore-prefixed ‘private’ attributes instead:
The above code only specifies a getter for the property; Python will not let you set a value for
Foo().spamnow:Of course, you can still access the ‘private’
_spamattribute from outside:You could use the double underscore convention, where attribute names with
__at the start (but not at the end!) are renamed on compilation. This is not meant for making a attribute inaccessible from the outside, it’s intent is to protect an attribute from being overwritten by a subclass instead.You can still access those attributes: