Skip to content

Instantly share code, notes, and snippets.

@robinrob
Last active June 5, 2018 08:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robinrob/0947770700cfe09707917fd677af07ba to your computer and use it in GitHub Desktop.
Save robinrob/0947770700cfe09707917fd677af07ba to your computer and use it in GitHub Desktop.
requirements.txt
venv
.history

Immutable Python class

Immutable is a class designed to create immutable instances. The attributes of any subclass of Immutable will be read-only.

Examples

Create a subclass of Immutable and initialise it:

class Dog(Immutable):
    def __init__(self, name, colour):
        super(TetrisPiece, self).__init__(attrs_dict={
            "name": name,
            "colour": colour
        })

misty = Dog("Misty", "black")

Run tests

  • Install Python 3
  • python3 -m venv venv
  • pip install
  • nosetests
"""Classes: Immutable."""
class Immutable(object):
"""Subclasses of Immutable will have immutable attributes."""
def __init__(self, attrs_dict=None): # noqa: D107
if attrs_dict is not None:
object.__setattr__(self, '_attrs_dict', attrs_dict)
else:
object.__setattr__(self, '_attrs_dict', {})
# Setting is prevented if attribute is already set
def __setattr__(self, attr, val):
"""Set attribute value if not already set."""
if attr in object.__getattribute__(self, '_attrs_dict'):
raise AttributeError(f"Attribute '{attr}' of {self.__class__.__name__} object is not writable'")
object.__getattribute__(self, '_attrs_dict')[attr] = val
# None is returned if attr is not set
def __getattribute__(self, attr):
"""Get attribute value."""
if attr in object.__getattribute__(self, '_attrs_dict'):
return object.__getattribute__(self, '_attrs_dict')[attr]
else:
try:
return object.__getattribute__(self, attr)
except AttributeError:
return None
def to_dict(self):
"""Get dictionary representation of this object's attributes."""
return object.__getattribute__(self, '_attrs_dict')
"""Unit tests for Immutable."""
import unittest
from immutable import Immutable
class ImmutableTestCase(unittest.TestCase): # noqa: D101
def test_should_get_attr(self): # noqa: D102
obj = Immutable()
obj.test = 'test'
self.assertEquals('test', obj.test)
def test_should_get_raise_attribute_error_when_attr_is_set_twice(self): # noqa: D102
obj = Immutable()
obj.test = 'test'
with self.assertRaises(AttributeError):
obj.test = 'new'
def test_should_get_none_when_attr_is_not_set(self): # noqa: D102
obj = Immutable()
self.assertEquals(None, obj.test)
def test_should_convert_to_dict(self): # noqa: D102
obj = Immutable()
obj.a = 'a'
obj.b = 'b'
dict = obj.to_dict()
self.assertIn('a', dict)
self.assertIn('b', dict)
self.assertEquals(obj.a, dict['a'])
self.assertEquals(obj.b, dict['b'])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment