To define a class with immutable instances, you can do something like this:
class Person:
"""Immutable person class"""
# Using __slots__ reduces memory usage.
__slots__ = ('name', 'age')
def __init__(self, name, age):
"""Create a Person instance.
Arguments:
name (str): Name of the person.
age: Age of the person.
"""
# Parameter validation. This shows how to do this,
# but you don't always want to be this inflexibe.
if not isinstance(name, str):
raise ValueError("'name' must be a string")
# Use super to set around __setattr__ definition
super(Person, self).__setattr__('name', name)
super(Person, self).__setattr__('age', int(age))
def __setattr__(self, name, value):
"""Prevent modification of attributes."""
raise AttributeError('Persons cannot be modified')
def __repr__(self):
"""Create a string representation of the Person.
You should always have at least __repr__ or __str__
for interactive use.
"""
template = "<Person(name='{}', age={})>"
return template.format(self.name, self.age)
A test:
In [2]: test = Person('S. Eggs', '42')
In [3]: str(test)
Out[3]: "<Person(name='S. Eggs', age=42)>"
In [4]: test.name
Out[4]: 'S. Eggs'
In [5]: test.age
Out[5]: 42
In [6]: test.name = 'foo'
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-6-1d0482a5f50c> in <module>()
----> 1 test.name = 'foo'
<ipython-input-1-efe979350b7b> in __setattr__(self, name, value)
24 def __setattr__(self, name, value):
25 """Prevent modification of attributes."""
---> 26 raise AttributeError('Persons cannot be modified')
27
28 def __repr__(self):
AttributeError: Persons cannot be modified