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.