python: immutable private class variables?
In Python the convention is to use a _
prefix on attribute names to mean protected
and a __
prefix to mean private
. This isn't enforced by the language; programmers are expected to know not to write code that relies on data that isn't public.
If you really wanted to enforce immutability, you could use a metaclass[docs] (the class of a class). Just modify __setattr__
and __delattr__
to raise exceptions when someone attempts to modify it, and make it a tuple
(an immutable list) [docs].
class FooMeta(type):
"""A type whose .thingies attribute can't be modified."""
def __setattr__(cls, name, value):
if name == "thingies":
raise AttributeError("Cannot modify .thingies")
else:
return type.__setattr__(cls, name, value)
def __delattr__(cls, name):
if name == "thingies":
raise AttributeError("Cannot delete .thingies")
else:
return type.__delattr__(cls, name)
thing1, thing2, thing3 = range(3)
class Foo(object):
__metaclass__ = FooMeta
thingies = (thing1, thing2, thing3)
other = [1, 2, 3]
Examples
print Foo.thingies # prints "(0, 1, 2)"
Foo.thingies = (1, 2) # raises an AttributeError
del Foo.thingies # raise an AttributeError
Foo.other = Foo.other + [4] # no exception
print Foo.other # prints "[1, 2, 3, 4]"
It would still technically be possible to modify these by going through the class's internal .__dict__
of attributes, but this should be enough to deter most users, it's very difficult to entirely secure Python objects.
You can't do either of those things in Python, not in the sense you do them in Java, anyway.
By convention, names prefixed with an underscore are considered private and should not be accessed outside the implementation, but nothing in Python enforces this convention. It's considered more of a warning that you're messing with an implementation detail that may change without warning in a future version of the code.