Class-level read-only properties in Python

The existing solutions are a bit complex — what about just ensuring that each class in a certain group has a unique metaclass, then setting a normal read-only property on the custom metaclass. Namely:

>>> class Meta(type):
...   def __new__(mcl, *a, **k):
...     uniquemcl = type('Uniq', (mcl,), {})
...     return type.__new__(uniquemcl, *a, **k)
... 
>>> class X: __metaclass__ = Meta
... 
>>> class Y: __metaclass__ = Meta
... 
>>> type(X).foo = property(lambda *_: 23)
>>> type(Y).foo = property(lambda *_: 45)
>>> X.foo
23
>>> Y.foo
45
>>> 

this is really much simpler, because it’s based on nothing more than the fact that when you get an instance’s attribute descriptors are looked up on the class (so of course when you get a class’s attribute descriptors are looked on the metaclass), and making class/metaclass unique isn’t terribly hard.

Oh, and of course:

>>> X.foo = 67
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

just to confirm it IS indeed read-only!

Leave a Comment