Python Forum
Correct way to implement immutable class
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Correct way to implement immutable class
#1
As of Python 3.6.5, what is the correct way to create an immutable object? Would you simply use a namedtuple? Or inherit from a namedtuple?
Reply
#2
Python doesn't have great facilities for building your own immutable things, unfortunately. I'm not sure you'd get much from inheriting from namedtuple, though you're welcome to try (and report back any successes), but using them directly is probably one of the closer things you can do to get immutability.
Reply
#3
namedtuple is a factory - not a class, but you can inherit from a tuple class you create.

Point = collections.namedtuple('Point', 'x y')
creates a class Point - that you may inherit. Some metaprogramming may help (definitely not a master at that).

This is a small example I've whipped on the fly (well, based on some code I've written before) - just to give you an idea
Output:
In [12]: import collections ...: import time ...: class Point: ...: def __new__(cls, **kwargs): ...: attributes, values = list(zip(*kwargs.items())) ...: instance = collections.namedtuple('_C_{:.0f}'.format(time.time()), attributes)(*values) ...: instance.__init__() ...: return instance ...: def __init__(self): ...: pass ...: In [13]: p = Point(x=1, y=2) In [14]: p.x Out[14]: 1
You can expand it the way you want.

PS That example, of course, is not inheritance - it's very basic metaprogramming


Allow me to introduce the real Python constructor __new__ Dance
Test everything in a Python shell (iPython, Azure Notebook, etc.)
  • Someone gave you an advice you liked? Test it - maybe the advice was actually bad.
  • Someone gave you an advice you think is bad? Test it before arguing - maybe it was good.
  • You posted a claim that something you did not test works? Be prepared to eat your hat.
Reply
#4
Can use attrs if don't want to implements this self.
Test frozen class.
attrs Wrote:Please note that true immutability is impossible in Python but it will get you 99% there.
pip install attrs
Test:
import attr

@attr.s(frozen=True)
class Foo:
     x = attr.ib()
     y = 5

>>> o = Foo(100)
>>> o.x
100
>>> o.x = 99
Traceback (most recent call last):
  File "<string>", line 449, in runcode
  File "<interactive input>", line 1, in <module>
  File "C:\python36\lib\site-packages\attr\_make.py", line 388, in _frozen_setattrs
    raise FrozenInstanceError()
attr.exceptions.FrozenInstanceError

# Can make new instance with attr.evolve()
>>> o_new = attr.evolve(o, x=99)
>>> o_new.x
99

>>> o.y
5
>>> o.y = 'hello'
Traceback (most recent call last):
  File "<string>", line 449, in runcode
  File "<interactive input>", line 1, in <module>
  File "C:\python36\lib\site-packages\attr\_make.py", line 388, in _frozen_setattrs
    raise FrozenInstanceError()
attr.exceptions.FrozenInstanceError
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Right way to implement interfaces yossiy123 1 1,218 May-12-2022, 10:31 AM
Last Post: Gribouillis
Question best way to implement algorithm hamidze 3 2,159 Feb-27-2021, 07:10 PM
Last Post: hamidze
  How to implement class register? AlekseyPython 0 1,955 Feb-14-2019, 06:19 AM
Last Post: AlekseyPython
  Immutable Book Class QueenSvetlana 10 6,147 Nov-27-2017, 07:31 PM
Last Post: buran

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020