1

I want to create object which is having read-only attributes. And it need to be initialize dynamically.

Here is situation I want.

readOnlyObject = ReadOnlyClass({'name': 'Tom', 'age': 24}) print(readOnlyObject.name) >> 'Tom' print(readOnlyObject.age) >> 24 readOnlyObject.age = 14 >> AttributeError: can't set attribute 

I found a way using property function,
but I think property function only works on attributes that is pre-declared.

Here is my code that property doesn't work.

class ReadOnlyClass: _preDeclaredVar = "Read-Only!" preDeclaredVar = property(lambda self: self._preDeclaredVar) def __init__(self, data: dict): for attr in data: setattr(self, '_' + attr, data[attr]) setattr(self, attr, property(lambda self: getattr(self, '_' + attr))) readOnlyObject = ReadOnlyClass({'name': 'Tom', 'age': 24}) print(readOnlyObject.preDeclaredVar) >> "Read-Only!" readOnlyObject.preDeclaredVar = "Can write?" >> AttributeError: can't set attribute ' print(readOnlyObject.name) >> <property object at 0x016C62A0> # I think it is weird.. property func only work on pre-declared variable? 

what happened?

I want to know is there a way to create read-only object dynamically.

1

2 Answers 2

1

Consider starting with __setattr__:

>>> class ReadOnlyClass: ... def __init__(self, **kwargs): ... self.__dict__.update(kwargs) ... ... def __setattr__(self, key, value): ... raise AttributeError("can't set attribute") ... >>> readonly_object = ReadOnlyClass(name='Tom', age=24) >>> readonly_object.name 'Tom' >>> readonly_object.age 24 >>> readonly_object.age = 10 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in __setattr__ AttributeError: can't set attribute 

However, this may not fully meet your expectations. You can still set the attributes through __dict__:

>>> readonly_object.__dict__['age'] = 10 >>> readonly_object.age 10 
Sign up to request clarification or add additional context in comments.

Comments

0

You can use Named tuples:

>>> import collections >>> def ReadOnlyClass(data): ... class_ = collections.namedtuple('ReadOnlyClass', data.keys()) ... return class_(**data) ... >>> readOnlyObject = ReadOnlyClass({'name': 'Tom', 'age': 24}) >>> print(readOnlyObject.name) Tom >>> print(readOnlyObject.age) 24 >>> readOnlyObject.age = 14 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: can't set attribute 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.